Compare commits

...
Sign in to create a new pull request.

43 commits

Author SHA1 Message Date
Fedora Release Engineering
27cb947638 Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild 2026-01-16 03:26:18 +00:00
Sumit Bose
30a6ef6bc2 Fix issue with restoring SELinux file label 2025-12-19 15:33:51 +01:00
Sumit Bose
2c56e5a7a2 Use selinux_requires_min to avoid policycoreutils-python-utils dependency
Resolves: rhbz#2422451
2025-12-16 12:01:55 +01:00
Sumit Bose
f793f7c317 Rebase to latest upstream version 2025-12-09 11:00:05 +01:00
Fedora Release Engineering
e2d83dd03e Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild 2025-07-23 16:44:52 +00:00
Fedora Release Engineering
c7e544d441 Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild 2025-01-16 10:34:02 +00:00
Sumit Bose
de0e3ba85a support for Samba's offline join and static analyser fixes 2024-11-27 19:28:39 +01:00
Fedora Release Engineering
aafe1deee2 Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild 2024-07-17 16:35:06 +00:00
Fedora Release Engineering
8a50fe9d1c Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild 2024-01-22 22:38:36 +00:00
Fedora Release Engineering
d5e5cbb731 Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild 2024-01-19 12:08:48 +00:00
Sumit Bose
2498cfad65 Migrated to SPDX license 2023-10-18 13:56:07 +00:00
Timm Bäder
7e8c213dc6 Use make macros 2023-10-18 13:28:16 +00:00
Fedora Release Engineering
e22d26d93d Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2023-07-19 12:53:22 +00:00
Fedora Release Engineering
b128d37655 Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2023-01-18 21:22:59 +00:00
Sumit Bose
3e5d9ce656 Update to upstream release 0.9.2 2022-09-29 08:20:32 +02:00
Fedora Release Engineering
023fa48ee0 Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2022-07-20 20:25:42 +00:00
Fedora Release Engineering
badb3d8a5f - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2022-01-19 20:54:58 +00:00
Sumit Bose
c47954a13f Add ns_get16() and ns_get32() to configure check
Resolves: rhbz#1984891
2021-07-28 14:36:59 +02:00
Fedora Release Engineering
d4ee038ec2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2021-07-21 17:14:50 +00:00
Fedora Release Engineering
d575416bf5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2021-07-21 12:19:40 +00:00
Sumit Bose
a299f31d7f Add user-passwd sub-command and setattr/delattr option
Resolves: rhbz#1690920, rhbz#1952828
2021-06-28 20:24:21 +02:00
Sumit Bose
a368b2fb84 Add fix for dont-expire-password option
Resolves: rhbz#1769644
2021-06-03 15:37:25 +02:00
Sumit Bose
a6fdb37cc3 Add dont-expire-password option and coverity fixes 2021-06-02 19:34:56 +02:00
Sumit Bose
c2d6ef0b1a Add macro updates for autoconf-2.71 and downstream gating 2021-04-07 11:29:06 +02:00
Sumit Bose
54a1f3a35f Add vendor error message
Resolves: rhbz#1889386
2021-03-29 14:22:21 +02:00
Sumit Bose
47faff9b58 Add Conflicts to avoid update/downgrade issues 2021-02-20 17:51:03 +01:00
Sumit Bose
078693fb25 Update to upstream release 0.9.1 2021-02-20 15:28:15 +01:00
Fedora Release Engineering
6aa58fb290 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2021-01-25 23:47:30 +00:00
Tom Stellard
05cc77c241 Add BuildRequires: make
https://fedoraproject.org/wiki/Changes/Remove_make_from_BuildRoot
2020-12-15 01:45:51 +00:00
Sumit Bose
7f6164b3c3 Include the latest upstream patches
- use-ldaps fixes
- man page improvements
- new sub-command to create managed service accounts
2020-11-13 08:36:13 +01:00
Sumit Bose
9b162ca3df man page and help output fixes 2020-08-14 06:49:01 +02:00
Fedora Release Engineering
59cb09d11c - Second attempt - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2020-07-31 23:48:38 +00:00
Fedora Release Engineering
15cd24121f - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2020-07-27 11:43:53 +00:00
Sumit Bose
d0eeced806 Include latest upstream patches
- delete: do not exit if keytab cannot be read
- tools: disable SSSD's locator plugin
2020-06-08 16:25:03 +02:00
Sumit Bose
c31b6fe1da Update to upstream release 0.9.0 and latest patches 2020-03-18 13:09:50 +01:00
Fedora Release Engineering
2c45753948 - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2020-01-28 11:11:43 +00:00
Sumit Bose
aeef2617bc various fixes and improvements
Resolves: rhbz#1683745, rhbz#1738573
2019-08-26 16:13:55 +02:00
Fedora Release Engineering
007aeec33f - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2019-07-24 17:32:25 +00:00
Jakub Hrozek
c2be30fe08 Resolves: rhbz#1727144 - adcli join fails with new krb5-libs; adcli needs to backport patches to only use permitted enctypes from upstream 2019-07-05 11:28:59 +02:00
Sumit Bose
603fc1b711 addition patch for rhbz#1630187 and new ones for rhbz#1588596
Resolves: rhbz#1630187, rhbz#1588596
2019-05-02 09:23:11 +02:00
Sumit Bose
8fc58f61c3 various fixes and improvements
Resolves: rhbz#1593240, rhbz#1608212, rhbz#1547014, rhbz#1547014,
          rhbz#1649868, rhbz#1588596, rhbz#1642546, rhbz#1595911,
          rhbz#1644311, rhbz#1337489, rhbz#1630187, rhbz#1622583
2019-03-22 18:30:43 +01:00
Fedora Release Engineering
8490450af9 - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2019-01-31 12:57:00 +00:00
Igor Gnatenko
5f117cba60
Remove obsolete ldconfig scriptlets
References: https://fedoraproject.org/wiki/Changes/RemoveObsoleteScriptlets
Signed-off-by: Igor Gnatenko <ignatenkobrain@fedoraproject.org>
2019-01-22 18:38:28 +01:00
29 changed files with 344 additions and 3471 deletions

4
.gitignore vendored
View file

@ -14,3 +14,7 @@
/adcli-0.7.6.tar.gz
/adcli-0.8.0.tar.gz
/adcli-0.8.2.tar.gz
/adcli-0.9.0.tar.gz
/adcli-0.9.1.tar.gz
/adcli-0.9.2.tar.gz
/adcli-0.9.3.1.tar.gz

View file

@ -1,31 +0,0 @@
From d8eb0f5704f34cb7d411cd275d32c63ead297b8d Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 24 Aug 2016 15:37:41 +0200
Subject: [PATCH 01/23] Remove upper-case only check when looking for the
NetBIOS name
It is a convention to use only upper-case letters for NetBIOS names but
it is not enforced on the AD-side. With the new option to specify a
random NetBIOS name it is possible to create host entries in AD with
lower-case letters in the name. To properly determine the name from the
keytab the upper-case check should be dropped,dc=
---
library/adenroll.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/library/adenroll.c b/library/adenroll.c
index a15e4be..d1020e9 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -1309,7 +1309,7 @@ load_keytab_entry (krb5_context k5,
if (!enroll->host_fqdn_explicit && !enroll->computer_name_explicit) {
/* Automatically use the netbios name */
- if (!enroll->computer_name && len > 1 && _adcli_str_is_up (name) &&
+ if (!enroll->computer_name && len > 1 &&
_adcli_str_has_suffix (name, "$") && !strchr (name, '/')) {
enroll->computer_name = name;
name[len - 1] = '\0';
--
2.14.4

View file

@ -0,0 +1,117 @@
From 9c31bb06590f2d96a2d6d8ce87dc3273c283a671 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 19 Dec 2025 14:48:13 +0100
Subject: [PATCH] enroll: fix issues if default keytab is used
librkb5 returns the default keytab with a 'FILE:' prefix which must be
removed before calling libselinux functions to operate on the keytab
file.
Resolves: https://issues.redhat.com/browse/RHEL-78631
---
library/adenroll.c | 32 ++++++++++++++++++++------------
library/adenroll.h | 3 +--
tools/computer.c | 6 +++---
3 files changed, 24 insertions(+), 17 deletions(-)
diff --git a/library/adenroll.c b/library/adenroll.c
index 20ad198..9484cbf 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -2116,30 +2116,38 @@ ensure_host_keytab (adcli_result res,
return ADCLI_SUCCESS;
}
-adcli_result
-ensure_host_keytab_selinux_context (adcli_result res,
- adcli_enroll *enroll)
+void
+restore_host_keytab_selinux_context (adcli_enroll *enroll)
{
#ifdef BUILD_SELINUX_POLICY
int ret;
-
- if (res != ADCLI_SUCCESS)
- return res;
+ krb5_context k5;
+ const char *name_start;
if (enroll->keytab_name == NULL) {
_adcli_info ("No keytab name available, skipping SELinux restorecon.");
- return ADCLI_SUCCESS;
+ return;
+ }
+
+ name_start = enroll->keytab_name;
+ if (strncmp (name_start, "FILE:", 5) == 0) {
+ name_start = enroll->keytab_name + 5;
}
- ret = selinux_restorecon (adcli_enroll_get_keytab_name (enroll), 0);
+ if (enroll->keytab != NULL) {
+ k5 = adcli_conn_get_krb5_context (enroll->conn);
+ krb5_kt_close (k5, enroll->keytab);
+ enroll->keytab = NULL;
+ }
+
+ ret = selinux_restorecon (name_start, 0);
if (ret != 0) {
- _adcli_err ("Failed to set SELinux context for %s with error %d: %s",
- enroll->keytab_name, ret, strerror (ret));
- return ADCLI_ERR_FAIL;
+ _adcli_err ("Failed to set SELinux context for %s with error %d: %s, ignored",
+ name_start, ret, strerror (errno));
}
#endif
- return ADCLI_SUCCESS;
+ return;
}
diff --git a/library/adenroll.h b/library/adenroll.h
index 79eb7a8..5aba81b 100644
--- a/library/adenroll.h
+++ b/library/adenroll.h
@@ -192,6 +192,5 @@ void adcli_enroll_set_samba_data_tool (adcli_enroll *enroll,
const char * adcli_enroll_get_samba_data_tool (adcli_enroll *enroll);
-adcli_result ensure_host_keytab_selinux_context (adcli_result res,
- adcli_enroll *enroll);
+void restore_host_keytab_selinux_context (adcli_enroll *enroll);
#endif /* ADENROLL_H_ */
diff --git a/tools/computer.c b/tools/computer.c
index ee027dc..f056366 100644
--- a/tools/computer.c
+++ b/tools/computer.c
@@ -520,7 +520,7 @@ adcli_tool_computer_join (adcli_conn *conn,
else if (show_password)
dump_password (conn, enroll);
- ensure_host_keytab_selinux_context (ADCLI_SUCCESS, enroll);
+ restore_host_keytab_selinux_context (enroll);
adcli_enroll_unref (enroll);
@@ -655,7 +655,7 @@ adcli_tool_computer_update (adcli_conn *conn,
else if (show_password)
dump_password (conn, enroll);
- ensure_host_keytab_selinux_context (ADCLI_SUCCESS, enroll);
+ restore_host_keytab_selinux_context (enroll);
adcli_enroll_unref (enroll);
@@ -1275,7 +1275,7 @@ adcli_tool_computer_managed_service_account (adcli_conn *conn,
else if (show_password)
dump_password (conn, enroll);
- ensure_host_keytab_selinux_context (ADCLI_SUCCESS, enroll);
+ restore_host_keytab_selinux_context (enroll);
adcli_enroll_unref (enroll);
--
2.52.0

View file

@ -1,31 +0,0 @@
From 4ba49015ca1ad98c03a209a11862f8e00d00fbd0 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 24 Aug 2016 16:19:36 +0200
Subject: [PATCH 02/23] Use strdup() if offset are used
Strings with an offset to the original starting point must be copied
because otherwise they cannot be properly freed later.
---
library/adenroll.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/library/adenroll.c b/library/adenroll.c
index d1020e9..05885d0 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -1318,9 +1318,9 @@ load_keytab_entry (krb5_context k5,
} else if (!enroll->host_fqdn && _adcli_str_has_prefix (name, "host/") && strchr (name, '.')) {
/* Skip host/ prefix */
- enroll->host_fqdn = name + 5;
- _adcli_info ("Found host qualified name in keytab: %s", name);
- name = NULL;
+ enroll->host_fqdn = strdup (name + 5);
+ return_val_if_fail (enroll->host_fqdn != NULL, FALSE);
+ _adcli_info ("Found host qualified name in keytab: %s", enroll->host_fqdn);
}
}
--
2.14.4

View file

@ -1,26 +0,0 @@
From 85fa595baf689e85c0d897c5eef73fdf1ecc1581 Mon Sep 17 00:00:00 2001
From: Striker Leggette <striker@redhat.com>
Date: Wed, 1 Nov 2017 11:16:39 +0100
Subject: [PATCH 03/23] correct spelling of 'adcli_tool_computer_delete'
description
---
tools/tools.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/tools.c b/tools/tools.c
index 4b243de..915130e 100644
--- a/tools/tools.c
+++ b/tools/tools.c
@@ -57,7 +57,7 @@ struct {
{ "update", adcli_tool_computer_update, "Update machine membership in a domain", },
{ "preset-computer", adcli_tool_computer_preset, "Pre setup computers accounts", },
{ "reset-computer", adcli_tool_computer_reset, "Reset a computer account", },
- { "delete-computer", adcli_tool_computer_delete, "Delete a computer acocunt", },
+ { "delete-computer", adcli_tool_computer_delete, "Delete a computer account", },
{ "create-user", adcli_tool_user_create, "Create a user account", },
{ "delete-user", adcli_tool_user_delete, "Delete a user account", },
{ "create-group", adcli_tool_group_create, "Create a group", },
--
2.14.4

View file

@ -1,37 +0,0 @@
From c3ec5121c1e79344ce615612ab3b576bc4745acb Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 1 Nov 2017 12:01:18 +0100
Subject: [PATCH 04/23] doc: explain that all credential cache types are
supported
---
doc/adcli.xml | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/doc/adcli.xml b/doc/adcli.xml
index e18ba5d..c54cc1b 100644
--- a/doc/adcli.xml
+++ b/doc/adcli.xml
@@ -118,11 +118,15 @@
is automatically discovered.</para></listitem>
</varlistentry>
<varlistentry>
- <term><option>-C, --login-ccache=<parameter>/path/to/file</parameter></option></term>
+ <term><option>-C, --login-ccache=<parameter>ccache_name</parameter></option></term>
<listitem><para>Use the specified kerberos credential
- cache to authenticate with the domain. If no file is specified or
- <option>-C</option> is used, then the default kerberos credential cache will
- be used.</para></listitem>
+ cache to authenticate with the domain. If no credential
+ cache is specified, the default kerberos credential
+ cache will be used. Credential caches of type FILE can
+ be given with the path to the file. For other
+ credential cache types, e.g. DIR, KEYRING or KCM, the
+ type must be specified explicitly together with a
+ suitable identifier.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-U, --login-user=<parameter>User</parameter></option></term>
--
2.14.4

View file

@ -1,38 +0,0 @@
From d2cdc54b0e51436c30ffaf19b0530aa446440367 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 1 Nov 2017 16:29:19 +0100
Subject: [PATCH 05/23] library: add adcli_conn_is_writeable()
---
library/adconn.c | 6 ++++++
library/adconn.h | 2 ++
2 files changed, 8 insertions(+)
diff --git a/library/adconn.c b/library/adconn.c
index a294dfd..67bdfd9 100644
--- a/library/adconn.c
+++ b/library/adconn.c
@@ -1528,3 +1528,9 @@ adcli_conn_server_has_capability (adcli_conn *conn,
return 0;
}
+
+bool adcli_conn_is_writeable (adcli_conn *conn)
+{
+ disco_dance_if_necessary (conn);
+ return ( (conn->domain_disco->flags & ADCLI_DISCO_WRITABLE) != 0);
+}
diff --git a/library/adconn.h b/library/adconn.h
index a0cb1f8..ed1cc58 100644
--- a/library/adconn.h
+++ b/library/adconn.h
@@ -144,4 +144,6 @@ void adcli_conn_set_krb5_conf_dir (adcli_conn *conn,
int adcli_conn_server_has_capability (adcli_conn *conn,
const char *capability);
+bool adcli_conn_is_writeable (adcli_conn *conn);
+
#endif /* ADCONN_H_ */
--
2.14.4

View file

@ -1,67 +0,0 @@
From 6b60f4c08d811e4bc3a68d1a4770c2ce5619c890 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 1 Nov 2017 17:14:05 +0100
Subject: [PATCH 06/23] Handle kvno increment for RODCs
Since the actual password change does not happen on the read-only domain
controller (RODC) the kvno change has to be replicated back which might
take some time. So we check the kvno before and after the change if we
are connected to a RODC and increment the kvno if needed.
---
library/adenroll.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/library/adenroll.c b/library/adenroll.c
index 05885d0..bb970d1 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -1633,8 +1633,30 @@ enroll_join_or_update_tasks (adcli_enroll *enroll,
adcli_enroll_flags flags)
{
adcli_result res;
+ krb5_kvno old_kvno = -1;
if (!(flags & ADCLI_ENROLL_PASSWORD_VALID)) {
+
+ /* Handle kvno changes for read-only domain controllers
+ * (RODC). Since the actual password change does not happen on
+ * the RODC the kvno change has to be replicated back which
+ * might take some time. So we check the kvno before and after
+ * the change if we are connected to a RODC and increment the
+ * kvno if needed. */
+ if (!adcli_conn_is_writeable (enroll->conn)) {
+ if (enroll->computer_attributes == NULL) {
+ res = retrieve_computer_account (enroll);
+ if (res != ADCLI_SUCCESS)
+ return res;
+ }
+ old_kvno = adcli_enroll_get_kvno (enroll);
+ _adcli_info ("Found old kvno '%d'", old_kvno);
+
+ ldap_msgfree (enroll->computer_attributes);
+ enroll->computer_attributes = NULL;
+ adcli_enroll_set_kvno (enroll, 0);
+ }
+
res = set_computer_password (enroll);
if (res != ADCLI_SUCCESS)
return res;
@@ -1651,6 +1673,15 @@ enroll_join_or_update_tasks (adcli_enroll *enroll,
return res;
}
+ /* Handle kvno changes for read-only domain controllers (RODC) */
+ if (!adcli_conn_is_writeable (enroll->conn) && old_kvno != -1 &&
+ adcli_enroll_get_kvno (enroll) != 0 &&
+ adcli_enroll_get_kvno (enroll) == old_kvno) {
+ enroll->kvno++;
+ _adcli_info ("No kvno change detected on read-only DC, kvno "
+ "will be incremented by 1 to '%d'", enroll->kvno);
+ }
+
/* We ignore failures of setting these fields */
update_and_calculate_enctypes (enroll);
update_computer_account (enroll);
--
2.14.4

View file

@ -1,28 +0,0 @@
From 3d312a6c89a88be444fb5ed768fbaa6155bf1cc9 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 30 Jan 2018 14:39:46 +0100
Subject: [PATCH 07/23] Fix memory leak in test_check_nt_time_string_lifetime
The test added with 650e5d33ef31437a049fb454ad3dc5457c56abe7 introduced
a small memory leak.
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
library/adutil.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/library/adutil.c b/library/adutil.c
index 21ccd27..cd40f45 100644
--- a/library/adutil.c
+++ b/library/adutil.c
@@ -501,6 +501,7 @@ test_check_nt_time_string_lifetime (void)
(time (NULL) + 10 + AD_TO_UNIX_TIME_CONST) * 1000 * 1000 *10)
!= -1);
assert (!_adcli_check_nt_time_string_lifetime (time_str, 0));
+ free (time_str);
/* This test will fail some time after 2200AD as a reminder to reflect
* why adcli is still needed. */
--
2.14.4

View file

@ -1,178 +0,0 @@
From f28edf4e887cf8616fa21dacc2b0f0d31f5f92fb Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 30 Jan 2018 14:37:05 +0100
Subject: [PATCH 08/23] library: add _adcli_bin_sid_to_str()
Convert a binary SID to the string representation.
https://bugs.freedesktop.org/show_bug.cgi?id=100118
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
library/adprivate.h | 4 ++
library/adutil.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 117 insertions(+)
diff --git a/library/adprivate.h b/library/adprivate.h
index fc146af..e99f9fc 100644
--- a/library/adprivate.h
+++ b/library/adprivate.h
@@ -31,6 +31,7 @@
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
+#include <stdint.h>
#include <ldap.h>
@@ -132,6 +133,9 @@ int _adcli_str_has_prefix (const char *str,
int _adcli_str_has_suffix (const char *str,
const char *suffix);
+char * _adcli_bin_sid_to_str (const uint8_t *data,
+ size_t len);
+
char * _adcli_str_dupn (void *data,
size_t len);
diff --git a/library/adutil.c b/library/adutil.c
index cd40f45..829cdd9 100644
--- a/library/adutil.c
+++ b/library/adutil.c
@@ -293,6 +293,83 @@ _adcli_strv_set (char ***field,
*field = newval;
}
+char *
+_adcli_bin_sid_to_str (const uint8_t *data,
+ size_t len)
+{
+ uint8_t sid_rev_num;
+ int8_t num_auths;
+ uint8_t id_auth[6];
+ uint32_t id_auth_val;
+ uint32_t sub_auths[15];
+ uint32_t val;
+ size_t p = 0;
+ size_t c;
+ int nc;
+ char *sid_buf;
+ size_t sid_buf_len;
+
+ if (data == NULL || len < 8) {
+ return NULL;
+ }
+
+ sid_rev_num = (uint8_t) data [p];
+ p++;
+
+ num_auths = (int8_t) data[p];
+ p++;
+
+ if (num_auths > 15 || len < 8 + (num_auths * sizeof (uint32_t))) {
+ return NULL;
+ }
+
+ for (c = 0; c < 6; c++) {
+ id_auth[c] = (uint8_t) data[p];
+ p++;
+ }
+
+ /* Only 32bits are used for the string representation */
+ id_auth_val = (id_auth[2] << 24) +
+ (id_auth[3] << 16) +
+ (id_auth[4] << 8) +
+ (id_auth[5]);
+
+ for (c = 0; c < num_auths; c++) {
+ memcpy (&val, data + p, sizeof (uint32_t));
+ sub_auths[c] = le32toh (val);
+
+ p += sizeof (uint32_t);
+ }
+
+ sid_buf_len = 17 + (num_auths * 11);
+ sid_buf = calloc (1, sid_buf_len);
+ if (sid_buf == NULL) {
+ return NULL;
+ }
+
+ nc = snprintf (sid_buf, sid_buf_len, "S-%u-%lu", sid_rev_num,
+ (unsigned long) id_auth_val);
+ if (nc < 0 || nc >= sid_buf_len) {
+ free (sid_buf);
+ return NULL;
+ }
+
+ p = 0;
+ for (c = 0; c < num_auths; c++) {
+ p += nc;
+ sid_buf_len -= nc;
+
+ nc = snprintf (sid_buf + p, sid_buf_len, "-%lu",
+ (unsigned long) sub_auths[c]);
+ if (nc < 0 || nc >= sid_buf_len) {
+ free (sid_buf);
+ return NULL;
+ }
+ }
+
+ return sid_buf;
+}
+
char *
_adcli_str_dupn (void *data,
size_t len)
@@ -508,6 +585,41 @@ test_check_nt_time_string_lifetime (void)
assert (_adcli_check_nt_time_string_lifetime ("130645404000000000", 100000));
}
+static void
+test_bin_sid_to_str (void)
+{
+ uint8_t sid1[] = { 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x15, 0x00, 0x00, 0x00, 0xF8, 0x12, 0x13, 0xDC,
+ 0x47, 0xF3, 0x1C, 0x76, 0x47, 0x2F, 0x2E, 0xD7,
+ 0x51, 0x04, 0x00, 0x00 };
+
+ uint8_t sid2[] = { 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x15, 0x00, 0x00, 0x00, 0xF8, 0x12, 0x13, 0xDC,
+ 0x47, 0xF3, 0x1C, 0x76, 0x47, 0x2F, 0x2E, 0xD7};
+
+ uint8_t sid3[] = { 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x15, 0x00, 0x00, 0x00, 0x29, 0xC9, 0x4F, 0xD9,
+ 0xC2, 0x3C, 0xC3, 0x78, 0x36, 0x55, 0x87, 0xF8};
+
+
+ char *str;
+
+ str = _adcli_bin_sid_to_str (sid1, sizeof (sid1));
+ assert (str != NULL);
+ assert (strcmp (str, "S-1-5-21-3692237560-1981608775-3610128199-1105") == 0);
+ free (str);
+
+ str = _adcli_bin_sid_to_str (sid2, sizeof (sid2));
+ assert (str != NULL);
+ assert (strcmp (str, "S-1-5-21-3692237560-1981608775-3610128199") == 0);
+ free (str);
+
+ str = _adcli_bin_sid_to_str (sid3, sizeof (sid2));
+ assert (str != NULL);
+ assert (strcmp (str, "S-1-5-21-3645884713-2026060994-4169618742") == 0);
+ free (str);
+}
+
int
main (int argc,
char *argv[])
@@ -516,6 +628,7 @@ main (int argc,
test_func (test_strv_dup, "/util/strv_dup");
test_func (test_strv_count, "/util/strv_count");
test_func (test_check_nt_time_string_lifetime, "/util/check_nt_time_string_lifetime");
+ test_func (test_bin_sid_to_str, "/util/bin_sid_to_str");
return test_run (argc, argv);
}
--
2.14.4

View file

@ -1,317 +0,0 @@
From 63576f12524f521c0cf08d42b279654885135a90 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 30 Jan 2018 14:39:17 +0100
Subject: [PATCH 09/23] library: add _adcli_call_external_program()
Allow adcli to call an external program given by an absolute path name
and an array of options. stdin and stdout can be used if needed.
https://bugs.freedesktop.org/show_bug.cgi?id=100118
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
configure.ac | 28 +++++++
library/adprivate.h | 6 ++
library/adutil.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 245 insertions(+)
diff --git a/configure.ac b/configure.ac
index 221d8ae..fe86638 100644
--- a/configure.ac
+++ b/configure.ac
@@ -263,6 +263,34 @@ AC_SUBST(LCOV)
AC_SUBST(GCOV)
AC_SUBST(GENHTML)
+AC_PATH_PROG(BIN_CAT, cat, no)
+if test "$BIN_CAT" = "no" ; then
+ AC_MSG_ERROR([cat is not available])
+else
+ AC_DEFINE_UNQUOTED(BIN_CAT, "$BIN_CAT", [path to cat, used in unit test])
+fi
+
+AC_PATH_PROG(BIN_TAC, tac, no)
+if test "$BIN_TAC" = "no" ; then
+ AC_MSG_ERROR([tac is not available])
+else
+ AC_DEFINE_UNQUOTED(BIN_TAC, "$BIN_TAC", [path to tac, used in unit test])
+fi
+
+AC_PATH_PROG(BIN_REV, rev, no)
+if test "$BIN_REV" = "no" ; then
+ AC_MSG_ERROR([rev is not available])
+else
+ AC_DEFINE_UNQUOTED(BIN_REV, "$BIN_REV", [path to rev, used in unit test])
+fi
+
+AC_PATH_PROG(BIN_ECHO, echo, no)
+if test "$BIN_ECHO" = "no" ; then
+ AC_MSG_ERROR([echo is not available])
+else
+ AC_DEFINE_UNQUOTED(BIN_ECHO, "$BIN_ECHO", [path to echo, used in unit test])
+fi
+
# ---------------------------------------------------------------------
ADCLI_LT_RELEASE=$ADCLI_CURRENT:$ADCLI_REVISION:$ADCLI_AGE
diff --git a/library/adprivate.h b/library/adprivate.h
index e99f9fc..7257c93 100644
--- a/library/adprivate.h
+++ b/library/adprivate.h
@@ -285,4 +285,10 @@ struct _adcli_attrs {
bool _adcli_check_nt_time_string_lifetime (const char *nt_time_string, unsigned int lifetime);
+adcli_result _adcli_call_external_program (const char *binary,
+ char * const *argv,
+ const char *stdin_data,
+ uint8_t **stdout_data,
+ size_t *stdout_data_len);
+
#endif /* ADPRIVATE_H_ */
diff --git a/library/adutil.c b/library/adutil.c
index 829cdd9..a27bd68 100644
--- a/library/adutil.c
+++ b/library/adutil.c
@@ -36,6 +36,7 @@
#include <unistd.h>
#include <stdint.h>
#include <time.h>
+#include <sys/wait.h>
static adcli_message_func message_func = NULL;
static char last_error[2048] = { 0, };
@@ -506,6 +507,161 @@ _adcli_check_nt_time_string_lifetime (const char *nt_time_string,
return false;
}
+adcli_result
+_adcli_call_external_program (const char *binary, char * const *argv,
+ const char *stdin_data,
+ uint8_t **stdout_data, size_t *stdout_data_len)
+{
+ int ret;
+ int pipefd_to_child[2] = { -1, -1};
+ int pipefd_from_child[2] = { -1, -1};
+ pid_t child_pid = 0;
+ int err;
+ size_t len;
+ ssize_t rlen;
+ pid_t wret;
+ int status;
+ uint8_t read_buf[4096];
+ uint8_t *out;
+
+ errno = 0;
+ ret = access (binary, X_OK);
+ if (ret != 0) {
+ err = errno;
+ _adcli_err ("Cannot run [%s]: [%d][%s].", binary, err,
+ strerror (err));
+ ret = ADCLI_ERR_FAIL;
+ goto done;
+ }
+
+ ret = pipe (pipefd_from_child);
+ if (ret == -1) {
+ err = errno;
+ _adcli_err ("pipe failed [%d][%s].", err, strerror (err));
+ ret = ADCLI_ERR_FAIL;
+ goto done;
+ }
+
+ ret = pipe (pipefd_to_child);
+ if (ret == -1) {
+ err = errno;
+ _adcli_err ("pipe failed [%d][%s].", err, strerror (err));
+ ret = ADCLI_ERR_FAIL;
+ goto done;
+ }
+
+ child_pid = fork ();
+
+ if (child_pid == 0) { /* child */
+ close (pipefd_to_child[1]);
+ ret = dup2 (pipefd_to_child[0], STDIN_FILENO);
+ if (ret == -1) {
+ err = errno;
+ _adcli_err ("dup2 failed [%d][%s].", err,
+ strerror (err));
+ exit (EXIT_FAILURE);
+ }
+
+ close (pipefd_from_child[0]);
+ ret = dup2 (pipefd_from_child[1], STDOUT_FILENO);
+ if (ret == -1) {
+ err = errno;
+ _adcli_err ("dup2 failed [%d][%s].", err,
+ strerror (err));
+ exit (EXIT_FAILURE);
+ }
+
+ execv (binary, argv);
+ _adcli_err ("Failed to run %s.", binary);
+ ret = ADCLI_ERR_FAIL;
+ goto done;
+ } else if (child_pid > 0) { /* parent */
+
+ if (stdin_data != NULL) {
+ len = strlen (stdin_data);
+ ret = write (pipefd_to_child[1], stdin_data, len);
+ if (ret != len) {
+ _adcli_err ("Failed to send computer account password "
+ "to net command.");
+ ret = ADCLI_ERR_FAIL;
+ goto done;
+ }
+ }
+
+ close (pipefd_to_child[0]);
+ pipefd_to_child[0] = -1;
+ close (pipefd_to_child[1]);
+ pipefd_to_child[0] = -1;
+
+ if (stdout_data != NULL || stdout_data_len != NULL) {
+ rlen = read (pipefd_from_child[0], read_buf, sizeof (read_buf));
+ if (rlen < 0) {
+ ret = errno;
+ _adcli_err ("Failed to read from child [%d][%s].\n",
+ ret, strerror (ret));
+ ret = ADCLI_ERR_FAIL;
+ goto done;
+ }
+
+ out = malloc (sizeof(uint8_t) * rlen);
+ if (out == NULL) {
+ _adcli_err ("Failed to allocate memory "
+ "for child output.");
+ ret = ADCLI_ERR_FAIL;
+ goto done;
+ } else {
+ memcpy (out, read_buf, rlen);
+ }
+
+ if (stdout_data != NULL) {
+ *stdout_data = out;
+ } else {
+ free (out);
+ }
+
+ if (stdout_data_len != NULL) {
+ *stdout_data_len = rlen;
+ }
+ }
+
+ } else {
+ _adcli_err ("Cannot run net command.");
+ ret = ADCLI_ERR_FAIL;
+ goto done;
+ }
+
+ ret = ADCLI_SUCCESS;
+
+done:
+ if (pipefd_from_child[0] != -1) {
+ close (pipefd_from_child[0]);
+ }
+ if (pipefd_from_child[1] != -1) {
+ close (pipefd_from_child[1]);
+ }
+ if (pipefd_to_child[0] != -1) {
+ close (pipefd_to_child[0]);
+ }
+ if (pipefd_to_child[1] != -1) {
+ close (pipefd_to_child[1]);
+ }
+
+ if (child_pid > 0) {
+ wret = waitpid (child_pid, &status, 0);
+ if (wret == -1) {
+ _adcli_err ("No sure what happend to net command.");
+ } else {
+ if (WIFEXITED (status)) {
+ _adcli_err ("net command failed with %d.",
+ WEXITSTATUS (status));
+ }
+ }
+ }
+
+ return ret;
+}
+
+
#ifdef UTIL_TESTS
#include "test.h"
@@ -620,6 +776,60 @@ test_bin_sid_to_str (void)
free (str);
}
+static void
+test_call_external_program (void)
+{
+ adcli_result res;
+ char *argv[] = { NULL, NULL, NULL };
+ uint8_t *stdout_data;
+ size_t stdout_data_len;
+
+ argv[0] = "/does/not/exists";
+ res = _adcli_call_external_program (argv[0], argv, NULL, NULL, NULL);
+ assert (res == ADCLI_ERR_FAIL);
+
+#ifdef BIN_CAT
+ argv[0] = BIN_CAT;
+ res = _adcli_call_external_program (argv[0], argv, "Hello",
+ &stdout_data, &stdout_data_len);
+ assert (res == ADCLI_SUCCESS);
+ assert (strncmp ("Hello", (char *) stdout_data, stdout_data_len) == 0);
+ free (stdout_data);
+
+ res = _adcli_call_external_program (argv[0], argv, "Hello",
+ NULL, NULL);
+ assert (res == ADCLI_SUCCESS);
+#endif
+
+#ifdef BIN_REV
+ argv[0] = BIN_REV;
+ res = _adcli_call_external_program (argv[0], argv, "Hello\n",
+ &stdout_data, &stdout_data_len);
+ assert (res == ADCLI_SUCCESS);
+ assert (strncmp ("olleH\n", (char *) stdout_data, stdout_data_len) == 0);
+ free (stdout_data);
+#endif
+
+#ifdef BIN_TAC
+ argv[0] = BIN_TAC;
+ res = _adcli_call_external_program (argv[0], argv, "Hello\nWorld\n",
+ &stdout_data, &stdout_data_len);
+ assert (res == ADCLI_SUCCESS);
+ assert (strncmp ("World\nHello\n", (char *) stdout_data, stdout_data_len) == 0);
+ free (stdout_data);
+#endif
+
+#ifdef BIN_ECHO
+ argv[0] = BIN_ECHO;
+ argv[1] = "Hello";
+ res = _adcli_call_external_program (argv[0], argv, NULL,
+ &stdout_data, &stdout_data_len);
+ assert (res == ADCLI_SUCCESS);
+ assert (strncmp ("Hello\n", (char *) stdout_data, stdout_data_len) == 0);
+ free (stdout_data);
+#endif
+}
+
int
main (int argc,
char *argv[])
@@ -629,6 +839,7 @@ main (int argc,
test_func (test_strv_count, "/util/strv_count");
test_func (test_check_nt_time_string_lifetime, "/util/check_nt_time_string_lifetime");
test_func (test_bin_sid_to_str, "/util/bin_sid_to_str");
+ test_func (test_call_external_program, "/util/call_external_program");
return test_run (argc, argv);
}
--
2.14.4

View file

@ -1,69 +0,0 @@
From bab08d90162c9146c1b4e8373f4b08209b84768c Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 30 Jan 2018 14:44:45 +0100
Subject: [PATCH 10/23] library: add _adcli_ldap_parse_sid()
Get a binary SID from a LDAP message and return it in the string
representation.
https://bugs.freedesktop.org/show_bug.cgi?id=100118
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
library/adldap.c | 24 ++++++++++++++++++++++++
library/adprivate.h | 4 ++++
2 files changed, 28 insertions(+)
diff --git a/library/adldap.c b/library/adldap.c
index 7c7a01b..07dc373 100644
--- a/library/adldap.c
+++ b/library/adldap.c
@@ -67,6 +67,30 @@ _adcli_ldap_handle_failure (LDAP *ldap,
return defres;
}
+char *
+_adcli_ldap_parse_sid (LDAP *ldap,
+ LDAPMessage *results,
+ const char *attr_name)
+{
+ LDAPMessage *entry;
+ struct berval **bvs;
+ char *val = NULL;
+
+ entry = ldap_first_entry (ldap, results);
+ if (entry != NULL) {
+ bvs = ldap_get_values_len (ldap, entry, attr_name);
+ if (bvs != NULL) {
+ if (bvs[0]) {
+ val = _adcli_bin_sid_to_str ( (uint8_t *) bvs[0]->bv_val,
+ bvs[0]->bv_len);
+ return_val_if_fail (val != NULL, NULL);
+ }
+ ldap_value_free_len (bvs);
+ }
+ }
+
+ return val;
+}
char *
_adcli_ldap_parse_value (LDAP *ldap,
diff --git a/library/adprivate.h b/library/adprivate.h
index 7257c93..83a88f6 100644
--- a/library/adprivate.h
+++ b/library/adprivate.h
@@ -174,6 +174,10 @@ adcli_result _adcli_ldap_handle_failure (LDAP *ldap,
const char *desc,
...) GNUC_PRINTF(3, 4);
+char * _adcli_ldap_parse_sid (LDAP *ldap,
+ LDAPMessage *results,
+ const char *attr_name);
+
char * _adcli_ldap_parse_value (LDAP *ldap,
LDAPMessage *results,
const char *attr_name);
--
2.14.4

View file

@ -1,71 +0,0 @@
From 3fa854b1439c039a2250cb24efadae6a66b0e9da Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 30 Jan 2018 14:40:46 +0100
Subject: [PATCH 11/23] library: add lookup_domain_sid()
Read the domain SID from the default naming context AD object and store
it in adcli_conn.
https://bugs.freedesktop.org/show_bug.cgi?id=100118
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
library/adconn.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/library/adconn.c b/library/adconn.c
index 67bdfd9..6b84b88 100644
--- a/library/adconn.c
+++ b/library/adconn.c
@@ -72,6 +72,7 @@ struct _adcli_conn_ctx {
char *domain_controller;
char *canonical_host;
char *domain_short;
+ char *domain_sid;
adcli_disco *domain_disco;
char *default_naming_context;
char *configuration_naming_context;
@@ -1068,6 +1069,32 @@ lookup_short_name (adcli_conn *conn)
}
}
+static void
+lookup_domain_sid (adcli_conn *conn)
+{
+ char *attrs[] = { "objectSid", NULL, };
+ LDAPMessage *results;
+ int ret;
+
+ free (conn->domain_sid);
+ conn->domain_sid = NULL;
+
+ ret = ldap_search_ext_s (conn->ldap, conn->default_naming_context, LDAP_SCOPE_BASE,
+ NULL, attrs, 0, NULL, NULL, NULL, -1, &results);
+ if (ret == LDAP_SUCCESS) {
+ conn->domain_sid = _adcli_ldap_parse_sid (conn->ldap, results, "objectSid");
+ ldap_msgfree (results);
+
+ if (conn->domain_sid)
+ _adcli_info ("Looked up domain SID: %s", conn->domain_sid);
+ else
+ _adcli_err ("No domain SID found");
+ } else {
+ _adcli_ldap_handle_failure (conn->ldap, ADCLI_ERR_DIRECTORY,
+ "Couldn't lookup domain SID");
+ }
+}
+
static void
conn_clear_state (adcli_conn *conn)
{
@@ -1148,6 +1175,7 @@ adcli_conn_connect (adcli_conn *conn)
return res;
lookup_short_name (conn);
+ lookup_domain_sid (conn);
return ADCLI_SUCCESS;
}
--
2.14.4

View file

@ -1,61 +0,0 @@
From f98c4f92091f6a68f390078f73be3bb6ca6e6550 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 30 Jan 2018 18:23:03 +0100
Subject: [PATCH 12/23] library: add adcli_conn_get_domain_sid()
https://bugs.freedesktop.org/show_bug.cgi?id=100118
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
library/adconn.c | 8 ++++++++
library/adconn.h | 2 ++
tools/computer.c | 1 +
3 files changed, 11 insertions(+)
diff --git a/library/adconn.c b/library/adconn.c
index 6b84b88..d2fb1d5 100644
--- a/library/adconn.c
+++ b/library/adconn.c
@@ -1355,6 +1355,14 @@ adcli_conn_get_domain_short (adcli_conn *conn)
return conn->domain_short;
}
+const char *
+adcli_conn_get_domain_sid (adcli_conn *conn)
+{
+ return_val_if_fail (conn != NULL, NULL);
+ return conn->domain_sid;
+}
+
+
LDAP *
adcli_conn_get_ldap_connection (adcli_conn *conn)
{
diff --git a/library/adconn.h b/library/adconn.h
index ed1cc58..13cfd32 100644
--- a/library/adconn.h
+++ b/library/adconn.h
@@ -91,6 +91,8 @@ void adcli_conn_set_domain_controller (adcli_conn *conn,
const char * adcli_conn_get_domain_short (adcli_conn *conn);
+const char * adcli_conn_get_domain_sid (adcli_conn *conn);
+
LDAP * adcli_conn_get_ldap_connection (adcli_conn *conn);
krb5_context adcli_conn_get_krb5_context (adcli_conn *conn);
diff --git a/tools/computer.c b/tools/computer.c
index d8a58c9..a3d0f03 100644
--- a/tools/computer.c
+++ b/tools/computer.c
@@ -43,6 +43,7 @@ dump_details (adcli_conn *conn,
printf ("domain-realm = %s\n", adcli_conn_get_domain_realm (conn));
printf ("domain-controller = %s\n", adcli_conn_get_domain_controller (conn));
printf ("domain-short = %s\n", adcli_conn_get_domain_short (conn));
+ printf ("domain-SID = %s\n", adcli_conn_get_domain_sid (conn));
printf ("naming-context = %s\n", adcli_conn_get_default_naming_context (conn));
printf ("domain-ou = %s\n", adcli_enroll_get_domain_ou (enroll));
--
2.14.4

View file

@ -1,142 +0,0 @@
From d362a0799618b576918f5c5d0625565484670ba2 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 30 Jan 2018 14:46:00 +0100
Subject: [PATCH 13/23] tools: add option --add-samba-data
https://bugs.freedesktop.org/show_bug.cgi?id=100118
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
doc/adcli.xml | 30 ++++++++++++++++++++++++++++++
library/adenroll.h | 1 +
tools/computer.c | 12 ++++++++++++
3 files changed, 43 insertions(+)
diff --git a/doc/adcli.xml b/doc/adcli.xml
index c54cc1b..fbc6c63 100644
--- a/doc/adcli.xml
+++ b/doc/adcli.xml
@@ -292,6 +292,21 @@ Password for Administrator:
machine account password. This is output in a format that should
be both human and machine readable.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--add-samba-data</option></term>
+ <listitem><para>After a successful join add the domain
+ SID and the machine account password to the Samba
+ specific databases by calling Samba's
+ <command>net</command> utility.</para>
+
+ <para>Please note that Samba's <command>net</command>
+ requires some settings in <filename>smb.conf</filename>
+ to create the database entries correctly. Most
+ important here is currently the
+ <option>workgroup</option> option, see
+ <citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for details.</para></listitem>
+ </varlistentry>
</variablelist>
</refsect1>
@@ -382,6 +397,21 @@ $ adcli update --login-ccache=/tmp/krbcc_123
about join operation. This is output in a format that should
be both human and machine readable.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--add-samba-data</option></term>
+ <listitem><para>After a successful join add the domain
+ SID and the machine account password to the Samba
+ specific databases by calling Samba's
+ <command>net</command> utility.</para>
+
+ <para>Please note that Samba's <command>net</command>
+ requires some settings in <filename>smb.conf</filename>
+ to create the database entries correctly. Most
+ important here is currently the
+ <option>workgroup</option> option, see
+ <citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for details.</para></listitem>
+ </varlistentry>
</variablelist>
</refsect1>
diff --git a/library/adenroll.h b/library/adenroll.h
index 9a107ab..32c9764 100644
--- a/library/adenroll.h
+++ b/library/adenroll.h
@@ -30,6 +30,7 @@ typedef enum {
ADCLI_ENROLL_NO_KEYTAB = 1 << 1,
ADCLI_ENROLL_ALLOW_OVERWRITE = 1 << 2,
ADCLI_ENROLL_PASSWORD_VALID = 1 << 3,
+ ADCLI_ENROLL_ADD_SAMBA_DATA = 1 << 3,
} adcli_enroll_flags;
typedef struct _adcli_enroll adcli_enroll;
diff --git a/tools/computer.c b/tools/computer.c
index a3d0f03..fc646f2 100644
--- a/tools/computer.c
+++ b/tools/computer.c
@@ -106,6 +106,7 @@ typedef enum {
opt_os_service_pack,
opt_user_principal,
opt_computer_password_lifetime,
+ opt_add_samba_data,
} Option;
static adcli_tool_desc common_usages[] = {
@@ -142,6 +143,8 @@ static adcli_tool_desc common_usages[] = {
"a successful join" },
{ opt_show_password, "show computer account password after after a\n"
"successful join" },
+ { opt_add_samba_data, "add domain SID and computer account password\n"
+ "to the Samba specific configuration database" },
{ opt_verbose, "show verbose progress and failure messages", },
{ 0 },
};
@@ -269,6 +272,7 @@ parse_option (Option opt,
case opt_show_details:
case opt_show_password:
case opt_one_time_password:
+ case opt_add_samba_data:
assert (0 && "not reached");
break;
}
@@ -326,6 +330,7 @@ adcli_tool_computer_join (adcli_conn *conn,
{ "user-principal", optional_argument, NULL, opt_user_principal },
{ "show-details", no_argument, NULL, opt_show_details },
{ "show-password", no_argument, NULL, opt_show_password },
+ { "add-samba-data", no_argument, NULL, opt_add_samba_data },
{ "verbose", no_argument, NULL, opt_verbose },
{ "help", no_argument, NULL, 'h' },
{ 0 },
@@ -352,6 +357,9 @@ adcli_tool_computer_join (adcli_conn *conn,
case opt_show_password:
show_password = 1;
break;
+ case opt_add_samba_data:
+ flags |= ADCLI_ENROLL_ADD_SAMBA_DATA;
+ break;
case 'h':
case '?':
case ':':
@@ -425,6 +433,7 @@ adcli_tool_computer_update (adcli_conn *conn,
{ "computer-password-lifetime", optional_argument, NULL, opt_computer_password_lifetime },
{ "show-details", no_argument, NULL, opt_show_details },
{ "show-password", no_argument, NULL, opt_show_password },
+ { "add-samba-data", no_argument, NULL, opt_add_samba_data },
{ "verbose", no_argument, NULL, opt_verbose },
{ "help", no_argument, NULL, 'h' },
{ 0 },
@@ -447,6 +456,9 @@ adcli_tool_computer_update (adcli_conn *conn,
case opt_show_password:
show_password = 1;
break;
+ case opt_add_samba_data:
+ flags |= ADCLI_ENROLL_ADD_SAMBA_DATA;
+ break;
case 'h':
case '?':
case ':':
--
2.14.4

View file

@ -1,75 +0,0 @@
From c090131e4f912f6f6c4f79eb40fbe500eb31c171 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 30 Jan 2018 18:24:15 +0100
Subject: [PATCH 14/23] tools: store Samba data if requested
Use Samba's net utility to add the machine account password and the
domain SID to the Samba configuration.
https://bugs.freedesktop.org/show_bug.cgi?id=100118
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
library/adenroll.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/library/adenroll.c b/library/adenroll.c
index bb970d1..20731cd 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -1533,6 +1533,36 @@ update_keytab_for_principals (adcli_enroll *enroll)
return ADCLI_SUCCESS;
}
+static adcli_result
+update_samba_data (adcli_enroll *enroll)
+{
+ int ret;
+ char *argv_pw[] = { "/usr/bin/net", "changesecretpw", "-i", "-f", NULL };
+ char *argv_sid[] = { "/usr/bin/net", "setdomainsid", NULL, NULL };
+
+ _adcli_info ("Trying to set Samba secret.\n");
+ ret = _adcli_call_external_program (argv_pw[0], argv_pw,
+ enroll->computer_password, NULL, NULL);
+ if (ret != ADCLI_SUCCESS) {
+ _adcli_err ("Failed to set Samba computer account password.\n");
+ }
+
+ argv_sid[2] = (char *) adcli_conn_get_domain_sid (enroll->conn);
+ if (argv_sid[2] == NULL) {
+ _adcli_err ("Domain SID not available.\n");
+ } else {
+ _adcli_info ("Trying to set domain SID %s for Samba.\n",
+ argv_sid[2]);
+ ret = _adcli_call_external_program (argv_sid[0], argv_sid,
+ NULL, NULL, NULL);
+ if (ret != ADCLI_SUCCESS) {
+ _adcli_err ("Failed to set Samba domain SID.\n");
+ }
+ }
+
+ return ret;
+}
+
static void
enroll_clear_state (adcli_enroll *enroll)
{
@@ -1687,6 +1717,15 @@ enroll_join_or_update_tasks (adcli_enroll *enroll,
update_computer_account (enroll);
update_service_principals (enroll);
+ if ( (flags & ADCLI_ENROLL_ADD_SAMBA_DATA) && ! (flags & ADCLI_ENROLL_PASSWORD_VALID)) {
+ res = update_samba_data (enroll);
+ if (res != ADCLI_SUCCESS) {
+ _adcli_info ("Failed to add Samba specific data, smbd "
+ "or winbindd might not work as "
+ "expected.\n");
+ }
+ }
+
if (flags & ADCLI_ENROLL_NO_KEYTAB)
return ADCLI_SUCCESS;
--
2.14.4

View file

@ -1,292 +0,0 @@
From 9b73f79a2436760b8278377014bf78a144a427ae Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 1 Feb 2018 14:26:22 +0100
Subject: [PATCH 15/23] make Samba data tool configurable
Allow to specify an alternative path to Samba's net utility at configure
time and at run time.
https://bugs.freedesktop.org/show_bug.cgi?id=100118
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
configure.ac | 13 ++++++++++++
doc/adcli.xml | 21 ++++++++++++++++++-
doc/samba_data_tool_path.xml.in | 1 +
library/adenroll.c | 46 ++++++++++++++++++++++++++++++++++-------
library/adenroll.h | 5 +++++
tools/computer.c | 16 ++++++++++++++
7 files changed, 95 insertions(+), 8 deletions(-)
create mode 100644 doc/samba_data_tool_path.xml.in
diff --git a/configure.ac b/configure.ac
index fe86638..68877c7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -291,6 +291,18 @@ else
AC_DEFINE_UNQUOTED(BIN_ECHO, "$BIN_ECHO", [path to echo, used in unit test])
fi
+AC_MSG_CHECKING([where is Samba's net utility])
+AC_ARG_WITH([samba_data_tool],
+ AC_HELP_STRING([--with-samba-data-tool=/path],
+ [Path to Samba's net utility]),
+ [],
+ [with_samba_data_tool=/usr/bin/net])
+AC_MSG_RESULT([$with_samba_data_tool])
+
+AC_DEFINE_UNQUOTED(SAMBA_DATA_TOOL, "$with_samba_data_tool",
+ [Path to Samba's net utility])
+
+AC_SUBST(SAMBA_DATA_TOOL, [$with_samba_data_tool])
# ---------------------------------------------------------------------
ADCLI_LT_RELEASE=$ADCLI_CURRENT:$ADCLI_REVISION:$ADCLI_AGE
@@ -300,6 +312,7 @@ AC_CONFIG_FILES([Makefile
build/Makefile
doc/Makefile
doc/version.xml
+ doc/samba_data_tool_path.xml
library/Makefile
tools/Makefile
])
diff --git a/doc/adcli.xml b/doc/adcli.xml
index fbc6c63..c2b7760 100644
--- a/doc/adcli.xml
+++ b/doc/adcli.xml
@@ -1,6 +1,9 @@
<?xml version='1.0'?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
- "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
+[
+ <!ENTITY samba_data_tool SYSTEM "samba_data_tool_path.xml">
+]>
<refentry id="adcli">
@@ -307,6 +310,14 @@ Password for Administrator:
<citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--samba-data-tool=<parameter>/path/to/net</parameter></option></term>
+ <listitem><para>If Samba's <command>net</command>
+ cannot be found at
+ <filename>&samba_data_tool;</filename> this option can
+ be used to specific an alternative location with the
+ help of an absolute path.</para></listitem>
+ </varlistentry>
</variablelist>
</refsect1>
@@ -412,6 +423,14 @@ $ adcli update --login-ccache=/tmp/krbcc_123
<citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--samba-data-tool=<parameter>/path/to/net</parameter></option></term>
+ <listitem><para>If Samba's <command>net</command>
+ cannot be found at
+ <filename>&samba_data_tool;</filename> this option can
+ be used to specific an alternative location with the
+ help of an absolute path.</para></listitem>
+ </varlistentry>
</variablelist>
</refsect1>
diff --git a/doc/samba_data_tool_path.xml.in b/doc/samba_data_tool_path.xml.in
new file mode 100644
index 0000000..a667c57
--- /dev/null
+++ b/doc/samba_data_tool_path.xml.in
@@ -0,0 +1 @@
+@SAMBA_DATA_TOOL@
diff --git a/library/adenroll.c b/library/adenroll.c
index 20731cd..a693049 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -42,6 +42,10 @@
#include <stdio.h>
#include <unistd.h>
+#ifndef SAMBA_DATA_TOOL
+#define SAMBA_DATA_TOOL "/usr/bin/net"
+#endif
+
static krb5_enctype v60_later_enctypes[] = {
ENCTYPE_AES256_CTS_HMAC_SHA1_96,
ENCTYPE_AES128_CTS_HMAC_SHA1_96,
@@ -100,6 +104,7 @@ struct _adcli_enroll {
int keytab_enctypes_explicit;
unsigned int computer_password_lifetime;
int computer_password_lifetime_explicit;
+ char *samba_data_tool;
};
static adcli_result
@@ -1537,26 +1542,33 @@ static adcli_result
update_samba_data (adcli_enroll *enroll)
{
int ret;
- char *argv_pw[] = { "/usr/bin/net", "changesecretpw", "-i", "-f", NULL };
- char *argv_sid[] = { "/usr/bin/net", "setdomainsid", NULL, NULL };
+ char *argv_pw[] = { NULL, "changesecretpw", "-i", "-f", NULL };
+ char *argv_sid[] = { NULL, "setdomainsid", NULL, NULL };
+
+ argv_pw[0] = (char *) adcli_enroll_get_samba_data_tool (enroll);
+ if (argv_pw[0] ==NULL) {
+ _adcli_err ("Samba data tool not available.");
+ return ADCLI_ERR_FAIL;
+ }
+ argv_sid[0] = argv_pw[0];
- _adcli_info ("Trying to set Samba secret.\n");
+ _adcli_info ("Trying to set Samba secret.");
ret = _adcli_call_external_program (argv_pw[0], argv_pw,
enroll->computer_password, NULL, NULL);
if (ret != ADCLI_SUCCESS) {
- _adcli_err ("Failed to set Samba computer account password.\n");
+ _adcli_err ("Failed to set Samba computer account password.");
}
argv_sid[2] = (char *) adcli_conn_get_domain_sid (enroll->conn);
if (argv_sid[2] == NULL) {
- _adcli_err ("Domain SID not available.\n");
+ _adcli_err ("Domain SID not available.");
} else {
- _adcli_info ("Trying to set domain SID %s for Samba.\n",
+ _adcli_info ("Trying to set domain SID %s for Samba.",
argv_sid[2]);
ret = _adcli_call_external_program (argv_sid[0], argv_sid,
NULL, NULL, NULL);
if (ret != ADCLI_SUCCESS) {
- _adcli_err ("Failed to set Samba domain SID.\n");
+ _adcli_err ("Failed to set Samba domain SID.");
}
}
@@ -1951,6 +1963,9 @@ adcli_enroll_new (adcli_conn *conn)
enroll->os_name = strdup (value);
return_val_if_fail (enroll->os_name != NULL, NULL);
+ enroll->samba_data_tool = strdup (SAMBA_DATA_TOOL);
+ return_val_if_fail (enroll->samba_data_tool != NULL, NULL);
+
return enroll;
}
@@ -1978,6 +1993,7 @@ enroll_free (adcli_enroll *enroll)
free (enroll->os_name);
free (enroll->os_version);
free (enroll->os_service_pack);
+ free (enroll->samba_data_tool);
free (enroll->user_principal);
_adcli_strv_free (enroll->service_names);
@@ -2343,3 +2359,19 @@ adcli_enroll_set_computer_password_lifetime (adcli_enroll *enroll,
enroll->computer_password_lifetime_explicit = 1;
}
+
+void
+adcli_enroll_set_samba_data_tool (adcli_enroll *enroll, const char *value)
+{
+ return_if_fail (enroll != NULL);
+ if (value != NULL && value[0] != '\0') {
+ _adcli_str_set (&enroll->samba_data_tool, value);
+ }
+}
+
+const char *
+adcli_enroll_get_samba_data_tool (adcli_enroll *enroll)
+{
+ return_val_if_fail (enroll != NULL, NULL);
+ return enroll->samba_data_tool;
+}
diff --git a/library/adenroll.h b/library/adenroll.h
index 32c9764..31ca0bc 100644
--- a/library/adenroll.h
+++ b/library/adenroll.h
@@ -141,4 +141,9 @@ const char * adcli_enroll_get_os_service_pack (adcli_enroll *enroll);
void adcli_enroll_set_os_service_pack (adcli_enroll *enroll,
const char *value);
+void adcli_enroll_set_samba_data_tool (adcli_enroll *enroll,
+ const char *value);
+
+const char * adcli_enroll_get_samba_data_tool (adcli_enroll *enroll);
+
#endif /* ADENROLL_H_ */
diff --git a/tools/computer.c b/tools/computer.c
index fc646f2..f86548b 100644
--- a/tools/computer.c
+++ b/tools/computer.c
@@ -30,6 +30,7 @@
#include <err.h>
#include <stdio.h>
#include <errno.h>
+#include <unistd.h>
static void
dump_details (adcli_conn *conn,
@@ -107,6 +108,7 @@ typedef enum {
opt_user_principal,
opt_computer_password_lifetime,
opt_add_samba_data,
+ opt_samba_data_tool,
} Option;
static adcli_tool_desc common_usages[] = {
@@ -145,6 +147,7 @@ static adcli_tool_desc common_usages[] = {
"successful join" },
{ opt_add_samba_data, "add domain SID and computer account password\n"
"to the Samba specific configuration database" },
+ { opt_samba_data_tool, "Absolute path to the tool used for add-samba-data" },
{ opt_verbose, "show verbose progress and failure messages", },
{ 0 },
};
@@ -160,6 +163,7 @@ parse_option (Option opt,
static int stdin_password = 0;
char *endptr;
unsigned int lifetime;
+ int ret;
switch (opt) {
case opt_login_ccache:
@@ -265,6 +269,16 @@ parse_option (Option opt,
adcli_enroll_set_computer_password_lifetime (enroll, lifetime);
return;
+ case opt_samba_data_tool:
+ errno = 0;
+ ret = access (optarg, X_OK);
+ if (ret != 0) {
+ ret = errno;
+ errx (EUSAGE, "Failed to access tool to add Samba data: %s", strerror (ret));
+ } else {
+ adcli_enroll_set_samba_data_tool (enroll, optarg);
+ }
+ return;
case opt_verbose:
return;
@@ -331,6 +345,7 @@ adcli_tool_computer_join (adcli_conn *conn,
{ "show-details", no_argument, NULL, opt_show_details },
{ "show-password", no_argument, NULL, opt_show_password },
{ "add-samba-data", no_argument, NULL, opt_add_samba_data },
+ { "samba-data-tool", no_argument, NULL, opt_samba_data_tool },
{ "verbose", no_argument, NULL, opt_verbose },
{ "help", no_argument, NULL, 'h' },
{ 0 },
@@ -434,6 +449,7 @@ adcli_tool_computer_update (adcli_conn *conn,
{ "show-details", no_argument, NULL, opt_show_details },
{ "show-password", no_argument, NULL, opt_show_password },
{ "add-samba-data", no_argument, NULL, opt_add_samba_data },
+ { "samba-data-tool", no_argument, NULL, opt_samba_data_tool },
{ "verbose", no_argument, NULL, opt_verbose },
{ "help", no_argument, NULL, 'h' },
{ 0 },
--
2.14.4

View file

@ -1,247 +0,0 @@
From f306f2f20c1d35fac63d27147824f039f7ef2d67 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 31 May 2018 18:27:37 +0200
Subject: [PATCH 16/23] Add trusted-for-delegation option
Resolves https://bugzilla.redhat.com/show_bug.cgi?id=1538730
---
doc/adcli.xml | 14 ++++++++++
library/adenroll.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
library/adenroll.h | 4 +++
tools/computer.c | 12 ++++++++
4 files changed, 108 insertions(+), 2 deletions(-)
diff --git a/doc/adcli.xml b/doc/adcli.xml
index c2b7760..b246190 100644
--- a/doc/adcli.xml
+++ b/doc/adcli.xml
@@ -283,6 +283,13 @@ Password for Administrator:
<option>--login-type=computer</option> and providing a
password as input.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--trusted-for-delegation=<parameter>yes|no|true|false</parameter></option></term>
+ <listitem><para>Set or unset the TRUSTED_FOR_DELEGATION
+ flag in the userAccountControl attribute to allow or
+ not allow that Kerberos tickets can be forwarded to the
+ host.</para></listitem>
+ </varlistentry>
<varlistentry>
<term><option>--show-details</option></term>
<listitem><para>After a successful join print out information
@@ -402,6 +409,13 @@ $ adcli update --login-ccache=/tmp/krbcc_123
in days. By default the password is updated if it is
older than 30 days.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--trusted-for-delegation=<parameter>yes|no|true|false</parameter></option></term>
+ <listitem><para>Set or unset the TRUSTED_FOR_DELEGATION
+ flag in the userAccountControl attribute to allow or
+ not allow that Kerberos tickets can be forwarded to the
+ host.</para></listitem>
+ </varlistentry>
<varlistentry>
<term><option>--show-details</option></term>
<listitem><para>After a successful join print out information
diff --git a/library/adenroll.c b/library/adenroll.c
index a693049..eca3c37 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -63,6 +63,13 @@ static krb5_enctype v51_earlier_enctypes[] = {
0
};
+/* Some constants for the userAccountControl AD LDAP attribute, see e.g.
+ * https://support.microsoft.com/en-us/help/305144/how-to-use-the-useraccountcontrol-flags-to-manipulate-user-account-pro
+ * for details. */
+#define UAC_WORKSTATION_TRUST_ACCOUNT 0x1000
+#define UAC_DONT_EXPIRE_PASSWORD 0x10000
+#define UAC_TRUSTED_FOR_DELEGATION 0x80000
+
struct _adcli_enroll {
int refs;
adcli_conn *conn;
@@ -105,6 +112,7 @@ struct _adcli_enroll {
unsigned int computer_password_lifetime;
int computer_password_lifetime_explicit;
char *samba_data_tool;
+ bool trusted_for_delegation;
};
static adcli_result
@@ -538,6 +546,10 @@ create_computer_account (adcli_enroll *enroll,
NULL,
};
+ if (adcli_enroll_get_trusted_for_delegation (enroll)) {
+ vals_userAccountControl[0] = "593920"; /* WORKSTATION_TRUST_ACCOUNT | DONT_EXPIRE_PASSWD | TRUSTED_FOR_DELEGATION */
+ }
+
ret = ldap_add_ext_s (ldap, enroll->computer_dn, mods, NULL, NULL);
/*
@@ -971,6 +983,7 @@ retrieve_computer_account (adcli_enroll *enroll)
"operatingSystemVersion",
"operatingSystemServicePack",
"pwdLastSet",
+ "userAccountControl",
NULL,
};
@@ -1149,6 +1162,47 @@ update_computer_attribute (adcli_enroll *enroll,
return res;
}
+static char *get_user_account_control (adcli_enroll *enroll)
+{
+ uint32_t uac = 0;
+ unsigned long attr_val;
+ char *uac_str;
+ LDAP *ldap;
+ char *end;
+
+ ldap = adcli_conn_get_ldap_connection (enroll->conn);
+ return_val_if_fail (ldap != NULL, NULL);
+
+ uac_str = _adcli_ldap_parse_value (ldap, enroll->computer_attributes, "userAccountControl");
+ if (uac_str != NULL) {
+
+ attr_val = strtoul (uac_str, &end, 10);
+ if (*end != '\0' || attr_val > UINT32_MAX) {
+ _adcli_warn ("Invalid userAccountControl '%s' for computer account in directory: %s, assuming 0",
+ uac_str, enroll->computer_dn);
+ } else {
+ uac = attr_val;
+ }
+ free (uac_str);
+ }
+
+ if (uac == 0) {
+ uac = UAC_WORKSTATION_TRUST_ACCOUNT | UAC_DONT_EXPIRE_PASSWORD;
+ }
+
+ if (adcli_enroll_get_trusted_for_delegation (enroll)) {
+ uac |= UAC_TRUSTED_FOR_DELEGATION;
+ } else {
+ uac &= ~(UAC_TRUSTED_FOR_DELEGATION);
+ }
+
+ if (asprintf (&uac_str, "%d", uac) < 0) {
+ return_val_if_reached (NULL);
+ }
+
+ return uac_str;
+}
+
static void
update_computer_account (adcli_enroll *enroll)
{
@@ -1167,11 +1221,16 @@ update_computer_account (adcli_enroll *enroll)
}
if (res == ADCLI_SUCCESS) {
- char *vals_userAccountControl[] = { "69632", NULL }; /* WORKSTATION_TRUST_ACCOUNT | DONT_EXPIRE_PASSWD */
+ char *vals_userAccountControl[] = { NULL , NULL };
LDAPMod userAccountControl = { LDAP_MOD_REPLACE, "userAccountControl", { vals_userAccountControl, } };
LDAPMod *mods[] = { &userAccountControl, NULL };
- res |= update_computer_attribute (enroll, ldap, mods);
+ vals_userAccountControl[0] = get_user_account_control (enroll);
+ if (vals_userAccountControl[0] != NULL) {
+ res |= update_computer_attribute (enroll, ldap, mods);
+ } else {
+ _adcli_warn ("Cannot update userAccountControl");
+ }
}
if (res == ADCLI_SUCCESS) {
@@ -2375,3 +2434,20 @@ adcli_enroll_get_samba_data_tool (adcli_enroll *enroll)
return_val_if_fail (enroll != NULL, NULL);
return enroll->samba_data_tool;
}
+
+bool
+adcli_enroll_get_trusted_for_delegation (adcli_enroll *enroll)
+{
+ return_val_if_fail (enroll != NULL, false);
+
+ return enroll->trusted_for_delegation;
+}
+
+void
+adcli_enroll_set_trusted_for_delegation (adcli_enroll *enroll,
+ bool value)
+{
+ return_if_fail (enroll != NULL);
+
+ enroll->trusted_for_delegation = value;
+}
diff --git a/library/adenroll.h b/library/adenroll.h
index 31ca0bc..be2ca18 100644
--- a/library/adenroll.h
+++ b/library/adenroll.h
@@ -109,6 +109,10 @@ unsigned int adcli_enroll_get_computer_password_lifetime (adcli_enroll *en
void adcli_enroll_set_computer_password_lifetime (adcli_enroll *enroll,
unsigned int lifetime);
+bool adcli_enroll_get_trusted_for_delegation (adcli_enroll *enroll);
+void adcli_enroll_set_trusted_for_delegation (adcli_enroll *enroll,
+ bool value);
+
krb5_kvno adcli_enroll_get_kvno (adcli_enroll *enroll);
void adcli_enroll_set_kvno (adcli_enroll *enroll,
diff --git a/tools/computer.c b/tools/computer.c
index f86548b..b905fd1 100644
--- a/tools/computer.c
+++ b/tools/computer.c
@@ -109,6 +109,7 @@ typedef enum {
opt_computer_password_lifetime,
opt_add_samba_data,
opt_samba_data_tool,
+ opt_trusted_for_delegation,
} Option;
static adcli_tool_desc common_usages[] = {
@@ -135,6 +136,8 @@ static adcli_tool_desc common_usages[] = {
{ opt_os_service_pack, "the computer operating system service pack", },
{ opt_user_principal, "add an authentication principal to the account", },
{ opt_computer_password_lifetime, "lifetime of the host accounts password in days", },
+ { opt_trusted_for_delegation, "set/unset the TRUSTED_FOR_DELEGATION flag\n"
+ "in the userAccountControl attribute", },
{ opt_no_password, "don't prompt for or read a password" },
{ opt_prompt_password, "prompt for a password if necessary" },
{ opt_stdin_password, "read a password from stdin (until EOF) if\n"
@@ -279,6 +282,13 @@ parse_option (Option opt,
adcli_enroll_set_samba_data_tool (enroll, optarg);
}
return;
+ case opt_trusted_for_delegation:
+ if (strcasecmp (optarg, "true") == 0 || strcasecmp (optarg, "yes") == 0) {
+ adcli_enroll_set_trusted_for_delegation (enroll, true);
+ } else {
+ adcli_enroll_set_trusted_for_delegation (enroll, false);
+ }
+ return;
case opt_verbose:
return;
@@ -342,6 +352,7 @@ adcli_tool_computer_join (adcli_conn *conn,
{ "os-version", required_argument, NULL, opt_os_version },
{ "os-service-pack", optional_argument, NULL, opt_os_service_pack },
{ "user-principal", optional_argument, NULL, opt_user_principal },
+ { "trusted-for-delegation", required_argument, NULL, opt_trusted_for_delegation },
{ "show-details", no_argument, NULL, opt_show_details },
{ "show-password", no_argument, NULL, opt_show_password },
{ "add-samba-data", no_argument, NULL, opt_add_samba_data },
@@ -446,6 +457,7 @@ adcli_tool_computer_update (adcli_conn *conn,
{ "os-service-pack", optional_argument, NULL, opt_os_service_pack },
{ "user-principal", optional_argument, NULL, opt_user_principal },
{ "computer-password-lifetime", optional_argument, NULL, opt_computer_password_lifetime },
+ { "trusted-for-delegation", required_argument, NULL, opt_trusted_for_delegation },
{ "show-details", no_argument, NULL, opt_show_details },
{ "show-password", no_argument, NULL, opt_show_password },
{ "add-samba-data", no_argument, NULL, opt_add_samba_data },
--
2.14.4

View file

@ -1,126 +0,0 @@
From 27c7dde2c0e84c3bb610d1aadb0fd8faff70d3fa Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 1 Jun 2018 21:26:47 +0200
Subject: [PATCH 17/23] Only update attributes given on the command line
When updating attributes of the LDAP computer object we only want to
update attributes which are related to options given on the command
line. Otherwise a simple call of 'adcli update' to check if the machine
account password needs an update might unexpectedly reset other
attributes as well.
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1547013
https://bugzilla.redhat.com/show_bug.cgi?id=1545568
https://bugzilla.redhat.com/show_bug.cgi?id=1538730
---
library/adenroll.c | 35 ++++++++++++++++++++++++++++++-----
1 file changed, 30 insertions(+), 5 deletions(-)
diff --git a/library/adenroll.c b/library/adenroll.c
index eca3c37..ee845ef 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -99,8 +99,11 @@ struct _adcli_enroll {
int user_princpal_generate;
char *os_name;
+ int os_name_explicit;
char *os_version;
+ int os_version_explicit;
char *os_service_pack;
+ int os_service_pack_explicit;
krb5_kvno kvno;
char *keytab_name;
@@ -113,6 +116,7 @@ struct _adcli_enroll {
int computer_password_lifetime_explicit;
char *samba_data_tool;
bool trusted_for_delegation;
+ int trusted_for_delegation_explicit;
};
static adcli_result
@@ -1212,7 +1216,11 @@ update_computer_account (adcli_enroll *enroll)
ldap = adcli_conn_get_ldap_connection (enroll->conn);
return_if_fail (ldap != NULL);
- {
+ /* Only update attributes which are explicitly given on the command
+ * line. Otherwise 'adcli update' must be always called with the same
+ * set of options to make sure existing attributes are not deleted or
+ * overwritten with different values. */
+ if (enroll->host_fqdn_explicit) {
char *vals_dNSHostName[] = { enroll->host_fqdn, NULL };
LDAPMod dNSHostName = { LDAP_MOD_REPLACE, "dNSHostName", { vals_dNSHostName, } };
LDAPMod *mods[] = { &dNSHostName, NULL };
@@ -1220,7 +1228,7 @@ update_computer_account (adcli_enroll *enroll)
res |= update_computer_attribute (enroll, ldap, mods);
}
- if (res == ADCLI_SUCCESS) {
+ if (res == ADCLI_SUCCESS && enroll->trusted_for_delegation_explicit) {
char *vals_userAccountControl[] = { NULL , NULL };
LDAPMod userAccountControl = { LDAP_MOD_REPLACE, "userAccountControl", { vals_userAccountControl, } };
LDAPMod *mods[] = { &userAccountControl, NULL };
@@ -1240,12 +1248,25 @@ update_computer_account (adcli_enroll *enroll)
LDAPMod operatingSystemVersion = { LDAP_MOD_REPLACE, "operatingSystemVersion", { vals_operatingSystemVersion, } };
char *vals_operatingSystemServicePack[] = { enroll->os_service_pack, NULL };
LDAPMod operatingSystemServicePack = { LDAP_MOD_REPLACE, "operatingSystemServicePack", { vals_operatingSystemServicePack, } };
- LDAPMod *mods[] = { &operatingSystem, &operatingSystemVersion, &operatingSystemServicePack, NULL };
+ LDAPMod *mods[] = { NULL, NULL, NULL, NULL };
+ size_t c = 0;
- res |= update_computer_attribute (enroll, ldap, mods);
+ if (enroll->os_name_explicit) {
+ mods[c++] = &operatingSystem;
+ }
+ if (enroll->os_version_explicit) {
+ mods[c++] = &operatingSystemVersion;
+ }
+ if (enroll->os_service_pack_explicit) {
+ mods[c++] = &operatingSystemServicePack;
+ }
+
+ if (c != 0) {
+ res |= update_computer_attribute (enroll, ldap, mods);
+ }
}
- if (res == ADCLI_SUCCESS) {
+ if (res == ADCLI_SUCCESS && !enroll->user_princpal_generate) {
char *vals_userPrincipalName[] = { enroll->user_principal, NULL };
LDAPMod userPrincipalName = { LDAP_MOD_REPLACE, "userPrincipalName", { vals_userPrincipalName, }, };
LDAPMod *mods[] = { &userPrincipalName, NULL, };
@@ -2337,6 +2358,7 @@ adcli_enroll_set_os_name (adcli_enroll *enroll,
if (value && value[0] == '\0')
value = NULL;
_adcli_str_set (&enroll->os_name, value);
+ enroll->os_name_explicit = 1;
}
const char *
@@ -2354,6 +2376,7 @@ adcli_enroll_set_os_version (adcli_enroll *enroll,
if (value && value[0] == '\0')
value = NULL;
_adcli_str_set (&enroll->os_version, value);
+ enroll->os_version_explicit = 1;
}
const char *
@@ -2371,6 +2394,7 @@ adcli_enroll_set_os_service_pack (adcli_enroll *enroll,
if (value && value[0] == '\0')
value = NULL;
_adcli_str_set (&enroll->os_service_pack, value);
+ enroll->os_service_pack_explicit = 1;
}
const char *
@@ -2450,4 +2474,5 @@ adcli_enroll_set_trusted_for_delegation (adcli_enroll *enroll,
return_if_fail (enroll != NULL);
enroll->trusted_for_delegation = value;
+ enroll->trusted_for_delegation_explicit = 1;
}
--
2.14.4

View file

@ -1,387 +0,0 @@
From 54c3d176326f719ffefded17bb797bc9e6c7f3c0 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 4 Jun 2018 10:49:33 +0200
Subject: [PATCH 18/23] update: allow to add service names
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1547013
https://bugzilla.redhat.com/show_bug.cgi?id=1545568
---
library/adenroll.c | 136 +++++++++++++++++++++++++++++++++-------------------
library/adkrb5.c | 113 +++++++++++++++++++++++++++++++++++++++++++
library/adprivate.h | 6 +++
3 files changed, 206 insertions(+), 49 deletions(-)
diff --git a/library/adenroll.c b/library/adenroll.c
index ee845ef..6fdc773 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -305,13 +305,37 @@ ensure_service_names (adcli_result res,
}
static adcli_result
-ensure_service_principals (adcli_result res,
- adcli_enroll *enroll)
+add_service_names_to_service_principals (adcli_enroll *enroll)
{
char *name;
int length = 0;
int i;
+ if (enroll->service_principals != NULL) {
+ length = seq_count (enroll->service_principals);
+ }
+
+ for (i = 0; enroll->service_names[i] != NULL; i++) {
+ if (asprintf (&name, "%s/%s", enroll->service_names[i], enroll->computer_name) < 0)
+ return_unexpected_if_reached ();
+ enroll->service_principals = _adcli_strv_add (enroll->service_principals,
+ name, &length);
+
+ if (enroll->host_fqdn) {
+ if (asprintf (&name, "%s/%s", enroll->service_names[i], enroll->host_fqdn) < 0)
+ return_unexpected_if_reached ();
+ enroll->service_principals = _adcli_strv_add (enroll->service_principals,
+ name, &length);
+ }
+ }
+
+ return ADCLI_SUCCESS;
+}
+
+static adcli_result
+ensure_service_principals (adcli_result res,
+ adcli_enroll *enroll)
+{
if (res != ADCLI_SUCCESS)
return res;
@@ -319,20 +343,7 @@ ensure_service_principals (adcli_result res,
if (!enroll->service_principals) {
assert (enroll->service_names != NULL);
-
- for (i = 0; enroll->service_names[i] != NULL; i++) {
- if (asprintf (&name, "%s/%s", enroll->service_names[i], enroll->computer_name) < 0)
- return_unexpected_if_reached ();
- enroll->service_principals = _adcli_strv_add (enroll->service_principals,
- name, &length);
-
- if (enroll->host_fqdn) {
- if (asprintf (&name, "%s/%s", enroll->service_names[i], enroll->host_fqdn) < 0)
- return_unexpected_if_reached ();
- enroll->service_principals = _adcli_strv_add (enroll->service_principals,
- name, &length);
- }
- }
+ return add_service_names_to_service_principals (enroll);
}
return ADCLI_SUCCESS;
@@ -356,6 +367,7 @@ ensure_keytab_principals (adcli_result res,
return_unexpected_if_fail (k5 != NULL);
enroll->keytab_principals = calloc (count + 3, sizeof (krb5_principal));
+ return_unexpected_if_fail (enroll->keytab_principals != NULL);
at = 0;
/* First add the principal for the computer account name */
@@ -1266,7 +1278,7 @@ update_computer_account (adcli_enroll *enroll)
}
}
- if (res == ADCLI_SUCCESS && !enroll->user_princpal_generate) {
+ if (res == ADCLI_SUCCESS && enroll->user_principal != NULL && !enroll->user_princpal_generate) {
char *vals_userPrincipalName[] = { enroll->user_principal, NULL };
LDAPMod userPrincipalName = { LDAP_MOD_REPLACE, "userPrincipalName", { vals_userPrincipalName, }, };
LDAPMod *mods[] = { &userPrincipalName, NULL, };
@@ -1519,7 +1531,8 @@ add_principal_to_keytab (adcli_enroll *enroll,
krb5_context k5,
krb5_principal principal,
const char *principal_name,
- int *which_salt)
+ int *which_salt,
+ adcli_enroll_flags flags)
{
match_principal_kvno closure;
krb5_data password;
@@ -1547,41 +1560,47 @@ add_principal_to_keytab (adcli_enroll *enroll,
enroll->keytab_name);
}
- password.data = enroll->computer_password;
- password.length = strlen (enroll->computer_password);
-
enctypes = adcli_enroll_get_keytab_enctypes (enroll);
- /*
- * So we need to discover which salt to use. As a side effect we are
- * also testing that our account works.
- */
+ if (flags & ADCLI_ENROLL_PASSWORD_VALID) {
+ code = _adcli_krb5_keytab_copy_entries (k5, enroll->keytab, principal,
+ enroll->kvno, enctypes);
+ } else {
- salts = build_principal_salts (enroll, k5, principal);
- return_unexpected_if_fail (salts != NULL);
+ password.data = enroll->computer_password;
+ password.length = strlen (enroll->computer_password);
- if (*which_salt < 0) {
- code = _adcli_krb5_keytab_discover_salt (k5, principal, enroll->kvno, &password,
- enctypes, salts, which_salt);
- if (code != 0) {
- _adcli_warn ("Couldn't authenticate with keytab while discovering which salt to use: %s: %s",
- principal_name, krb5_get_error_message (k5, code));
- *which_salt = DEFAULT_SALT;
- } else {
- assert (*which_salt >= 0);
- _adcli_info ("Discovered which keytab salt to use");
+ /*
+ * So we need to discover which salt to use. As a side effect we are
+ * also testing that our account works.
+ */
+
+ salts = build_principal_salts (enroll, k5, principal);
+ return_unexpected_if_fail (salts != NULL);
+
+ if (*which_salt < 0) {
+ code = _adcli_krb5_keytab_discover_salt (k5, principal, enroll->kvno, &password,
+ enctypes, salts, which_salt);
+ if (code != 0) {
+ _adcli_warn ("Couldn't authenticate with keytab while discovering which salt to use: %s: %s",
+ principal_name, krb5_get_error_message (k5, code));
+ *which_salt = DEFAULT_SALT;
+ } else {
+ assert (*which_salt >= 0);
+ _adcli_info ("Discovered which keytab salt to use");
+ }
}
- }
- code = _adcli_krb5_keytab_add_entries (k5, enroll->keytab, principal,
- enroll->kvno, &password, enctypes, &salts[*which_salt]);
+ code = _adcli_krb5_keytab_add_entries (k5, enroll->keytab, principal,
+ enroll->kvno, &password, enctypes, &salts[*which_salt]);
- free_principal_salts (k5, salts);
+ free_principal_salts (k5, salts);
- if (code != 0) {
- _adcli_err ("Couldn't add keytab entries: %s: %s",
- enroll->keytab_name, krb5_get_error_message (k5, code));
- return ADCLI_ERR_FAIL;
+ if (code != 0) {
+ _adcli_err ("Couldn't add keytab entries: %s: %s",
+ enroll->keytab_name, krb5_get_error_message (k5, code));
+ return ADCLI_ERR_FAIL;
+ }
}
@@ -1591,7 +1610,8 @@ add_principal_to_keytab (adcli_enroll *enroll,
}
static adcli_result
-update_keytab_for_principals (adcli_enroll *enroll)
+update_keytab_for_principals (adcli_enroll *enroll,
+ adcli_enroll_flags flags)
{
krb5_context k5;
adcli_result res;
@@ -1608,7 +1628,7 @@ update_keytab_for_principals (adcli_enroll *enroll)
if (krb5_unparse_name (k5, enroll->keytab_principals[i], &name) != 0)
name = "";
res = add_principal_to_keytab (enroll, k5, enroll->keytab_principals[i],
- name, &which_salt);
+ name, &which_salt, flags);
krb5_free_unparsed_name (k5, name);
if (res != ADCLI_SUCCESS)
@@ -1807,6 +1827,20 @@ enroll_join_or_update_tasks (adcli_enroll *enroll,
/* We ignore failures of setting these fields */
update_and_calculate_enctypes (enroll);
update_computer_account (enroll);
+
+ /* service_names is only set from input on the command line, so no
+ * additional check for explicit is needed here */
+ if (enroll->service_names != NULL) {
+ res = add_service_names_to_service_principals (enroll);
+ if (res != ADCLI_SUCCESS) {
+ return res;
+ }
+ res = ensure_keytab_principals (res, enroll);
+ if (res != ADCLI_SUCCESS) {
+ return res;
+ }
+ }
+
update_service_principals (enroll);
if ( (flags & ADCLI_ENROLL_ADD_SAMBA_DATA) && ! (flags & ADCLI_ENROLL_PASSWORD_VALID)) {
@@ -1826,7 +1860,7 @@ enroll_join_or_update_tasks (adcli_enroll *enroll,
* that we use for salting.
*/
- return update_keytab_for_principals (enroll);
+ return update_keytab_for_principals (enroll, flags);
}
adcli_result
@@ -1927,7 +1961,11 @@ adcli_enroll_update (adcli_enroll *enroll,
if (_adcli_check_nt_time_string_lifetime (value,
adcli_enroll_get_computer_password_lifetime (enroll))) {
- flags |= ADCLI_ENROLL_NO_KEYTAB;
+ /* Do not update keytab if neither new service principals have
+ * to be added nor the user principal has to be changed. */
+ if (enroll->service_names == NULL && (enroll->user_principal == NULL || enroll->user_princpal_generate)) {
+ flags |= ADCLI_ENROLL_NO_KEYTAB;
+ }
flags |= ADCLI_ENROLL_PASSWORD_VALID;
}
free (value);
diff --git a/library/adkrb5.c b/library/adkrb5.c
index b0e903e..033c181 100644
--- a/library/adkrb5.c
+++ b/library/adkrb5.c
@@ -204,6 +204,119 @@ _adcli_krb5_open_keytab (krb5_context k5,
return ADCLI_SUCCESS;
}
+typedef struct {
+ krb5_kvno kvno;
+ krb5_enctype enctype;
+ int matched;
+} match_enctype_kvno;
+
+static krb5_boolean
+match_enctype_and_kvno (krb5_context k5,
+ krb5_keytab_entry *entry,
+ void *data)
+{
+ krb5_boolean similar = FALSE;
+ match_enctype_kvno *closure = data;
+ krb5_error_code code;
+
+ assert (closure->enctype);
+
+ code = krb5_c_enctype_compare (k5, closure->enctype, entry->key.enctype,
+ &similar);
+
+ if (code == 0 && entry->vno == closure->kvno && similar) {
+ closure->matched = 1;
+ return 1;
+ }
+
+ return 0;
+}
+
+static krb5_error_code
+_adcli_krb5_get_keyblock (krb5_context k5,
+ krb5_keytab keytab,
+ krb5_keyblock *keyblock,
+ krb5_boolean (* match_func) (krb5_context,
+ krb5_keytab_entry *,
+ void *),
+ void *match_data)
+{
+ krb5_kt_cursor cursor;
+ krb5_keytab_entry entry;
+ krb5_error_code code;
+
+ code = krb5_kt_start_seq_get (k5, keytab, &cursor);
+ if (code == KRB5_KT_END || code == ENOENT)
+ return 0;
+ else if (code != 0)
+ return code;
+
+ for (;;) {
+ code = krb5_kt_next_entry (k5, keytab, &entry, &cursor);
+ if (code != 0)
+ break;
+
+ /* See if we should remove this entry */
+ if (!match_func (k5, &entry, match_data)) {
+ krb5_free_keytab_entry_contents (k5, &entry);
+ continue;
+ }
+
+ code = krb5_copy_keyblock_contents (k5, &entry.key, keyblock);
+ krb5_free_keytab_entry_contents (k5, &entry);
+ break;
+
+
+ }
+
+ if (code == KRB5_KT_END)
+ code = 0;
+
+ krb5_kt_end_seq_get (k5, keytab, &cursor);
+ return code;
+}
+
+krb5_error_code
+_adcli_krb5_keytab_copy_entries (krb5_context k5,
+ krb5_keytab keytab,
+ krb5_principal principal,
+ krb5_kvno kvno,
+ krb5_enctype *enctypes)
+{
+ krb5_keytab_entry entry;
+ krb5_error_code code;
+ int i;
+ match_enctype_kvno closure;
+
+ for (i = 0; enctypes[i] != 0; i++) {
+
+ closure.kvno = kvno;
+ closure.enctype = enctypes[i];
+ closure.matched = 0;
+
+ memset (&entry, 0, sizeof (entry));
+
+ code = _adcli_krb5_get_keyblock (k5, keytab, &entry.key,
+ match_enctype_and_kvno, &closure);
+ if (code != 0) {
+ return code;
+ }
+
+
+ entry.principal = principal;
+ entry.vno = kvno;
+
+ code = krb5_kt_add_entry (k5, keytab, &entry);
+
+ entry.principal = NULL;
+ krb5_free_keytab_entry_contents (k5, &entry);
+
+ if (code != 0)
+ return code;
+ }
+
+ return 0;
+}
krb5_error_code
_adcli_krb5_keytab_add_entries (krb5_context k5,
diff --git a/library/adprivate.h b/library/adprivate.h
index 83a88f6..7485249 100644
--- a/library/adprivate.h
+++ b/library/adprivate.h
@@ -282,6 +282,12 @@ krb5_enctype * _adcli_krb5_parse_enctypes (const char *value);
char * _adcli_krb5_format_enctypes (krb5_enctype *enctypes);
+krb5_error_code _adcli_krb5_keytab_copy_entries (krb5_context k5,
+ krb5_keytab keytab,
+ krb5_principal principal,
+ krb5_kvno kvno,
+ krb5_enctype *enctypes);
+
struct _adcli_attrs {
LDAPMod **mods;
int len;
--
2.14.4

View file

@ -1,181 +0,0 @@
From 9ad1164405e7b4decb7c4ad96fe5ab27d6e53366 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 6 Jun 2018 16:31:32 +0200
Subject: [PATCH 19/23] Calculate enctypes in a separate function
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1542354
---
library/adenroll.c | 137 +++++++++++++++++++++++++++++++----------------------
1 file changed, 81 insertions(+), 56 deletions(-)
diff --git a/library/adenroll.c b/library/adenroll.c
index 6fdc773..75ac1e4 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -542,6 +542,83 @@ calculate_computer_account (adcli_enroll *enroll,
return ADCLI_SUCCESS;
}
+static adcli_result
+calculate_enctypes (adcli_enroll *enroll, char **enctype)
+{
+ char *value = NULL;
+ krb5_enctype *read_enctypes;
+ char *new_value = NULL;
+ int is_2008_or_later;
+ LDAP *ldap;
+
+ *enctype = NULL;
+ /*
+ * Because we're using a keytab we want the server to be aware of the
+ * encryption types supported on the client, because we can't dynamically
+ * use a new one that's thrown at us.
+ *
+ * If the encryption types are not explicitly set by the caller of this
+ * library, then see if the account already has some encryption types
+ * marked on it.
+ *
+ * If not, write our default set to the account.
+ *
+ * Note that Windows 2003 and earlier have a standard set of encryption
+ * types, and no msDS-supportedEncryptionTypes attribute.
+ */
+
+ ldap = adcli_conn_get_ldap_connection (enroll->conn);
+ return_unexpected_if_fail (ldap != NULL);
+
+ is_2008_or_later = adcli_conn_server_has_capability (enroll->conn, ADCLI_CAP_V60_OID);
+
+ /* In 2008 or later, use the msDS-supportedEncryptionTypes attribute */
+ if (is_2008_or_later) {
+ value = _adcli_ldap_parse_value (ldap, enroll->computer_attributes,
+ "msDS-supportedEncryptionTypes");
+
+ if (!enroll->keytab_enctypes_explicit && value != NULL) {
+ read_enctypes = _adcli_krb5_parse_enctypes (value);
+ if (read_enctypes == NULL) {
+ _adcli_warn ("Invalid or unsupported encryption types are set on "
+ "the computer account (%s).", value);
+ } else {
+ free (enroll->keytab_enctypes);
+ enroll->keytab_enctypes = read_enctypes;
+ }
+ }
+
+ /* In 2003 or earlier, standard set of enc types */
+ } else {
+ value = _adcli_krb5_format_enctypes (v51_earlier_enctypes);
+ }
+
+ new_value = _adcli_krb5_format_enctypes (adcli_enroll_get_keytab_enctypes (enroll));
+ if (new_value == NULL) {
+ free (value);
+ _adcli_warn ("The encryption types desired are not available in active directory");
+ return ADCLI_ERR_CONFIG;
+ }
+
+ /* If we already have this value, then don't need to update */
+ if (value && strcmp (new_value, value) == 0) {
+ free (value);
+ free (new_value);
+ return ADCLI_SUCCESS;
+ }
+ free (value);
+
+ if (!is_2008_or_later) {
+ free (new_value);
+ _adcli_warn ("Server does not support setting encryption types");
+ return ADCLI_SUCCESS;
+ }
+
+ *enctype = new_value;
+ return ADCLI_SUCCESS;
+}
+
+
static adcli_result
create_computer_account (adcli_enroll *enroll,
LDAP *ldap)
@@ -1053,75 +1130,23 @@ retrieve_computer_account (adcli_enroll *enroll)
static adcli_result
update_and_calculate_enctypes (adcli_enroll *enroll)
{
- char *value = NULL;
- krb5_enctype *read_enctypes;
char *vals_supportedEncryptionTypes[] = { NULL, NULL };
LDAPMod mod = { LDAP_MOD_REPLACE, "msDS-supportedEncryptionTypes", { vals_supportedEncryptionTypes, } };
LDAPMod *mods[2] = { &mod, NULL };
- int is_2008_or_later;
char *new_value;
LDAP *ldap;
int ret;
- /*
- * Because we're using a keytab we want the server to be aware of the
- * encryption types supported on the client, because we can't dynamically
- * use a new one that's thrown at us.
- *
- * If the encryption types are not explicitly set by the caller of this
- * library, then see if the account already has some encryption types
- * marked on it.
- *
- * If not, write our default set to the account.
- *
- * Note that Windows 2003 and earlier have a standard set of encryption
- * types, and no msDS-supportedEncryptionTypes attribute.
- */
-
ldap = adcli_conn_get_ldap_connection (enroll->conn);
return_unexpected_if_fail (ldap != NULL);
- is_2008_or_later = adcli_conn_server_has_capability (enroll->conn, ADCLI_CAP_V60_OID);
-
- /* In 2008 or later, use the msDS-supportedEncryptionTypes attribute */
- if (is_2008_or_later) {
- value = _adcli_ldap_parse_value (ldap, enroll->computer_attributes,
- "msDS-supportedEncryptionTypes");
-
- if (!enroll->keytab_enctypes_explicit && value != NULL) {
- read_enctypes = _adcli_krb5_parse_enctypes (value);
- if (read_enctypes == NULL) {
- _adcli_warn ("Invalid or unsupported encryption types are set on "
- "the computer account (%s).", value);
- } else {
- free (enroll->keytab_enctypes);
- enroll->keytab_enctypes = read_enctypes;
- }
- }
-
- /* In 2003 or earlier, standard set of enc types */
- } else {
- value = _adcli_krb5_format_enctypes (v51_earlier_enctypes);
- }
-
- new_value = _adcli_krb5_format_enctypes (adcli_enroll_get_keytab_enctypes (enroll));
- if (new_value == NULL) {
- free (value);
- _adcli_warn ("The encryption types desired are not available in active directory");
- return ADCLI_ERR_CONFIG;
- }
-
- /* If we already have this value, then don't need to update */
- if (value && strcmp (new_value, value) == 0) {
- free (value);
+ ret = calculate_enctypes (enroll, &new_value);
+ if (ret != ADCLI_SUCCESS) {
free (new_value);
- return ADCLI_SUCCESS;
+ return ret;
}
- free (value);
- if (!is_2008_or_later) {
- free (new_value);
- _adcli_warn ("Server does not support setting encryption types");
+ if (new_value == NULL) {
return ADCLI_SUCCESS;
}
--
2.14.4

View file

@ -1,110 +0,0 @@
From cbe33b3e6d0d3415e4642d71942380d1793311f1 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 11 Jun 2018 09:44:49 +0200
Subject: [PATCH 20/23] join: add all attributes while creating computer object
It is possible to create special accounts which can only join a computer
to a domain but is not allowed to do any further operations which the
computer object. As a result if such an account is used during the join
only the ldapadd operation is permitted but not any later ldapmodify
operation. To create the computer object correctly in this case all
attributes must be added while the object is created and not later.
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1542354
---
library/adenroll.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 47 insertions(+), 5 deletions(-)
diff --git a/library/adenroll.c b/library/adenroll.c
index 75ac1e4..b508caf 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -573,7 +573,7 @@ calculate_enctypes (adcli_enroll *enroll, char **enctype)
is_2008_or_later = adcli_conn_server_has_capability (enroll->conn, ADCLI_CAP_V60_OID);
/* In 2008 or later, use the msDS-supportedEncryptionTypes attribute */
- if (is_2008_or_later) {
+ if (is_2008_or_later && enroll->computer_attributes != NULL) {
value = _adcli_ldap_parse_value (ldap, enroll->computer_attributes,
"msDS-supportedEncryptionTypes");
@@ -618,7 +618,6 @@ calculate_enctypes (adcli_enroll *enroll, char **enctype)
return ADCLI_SUCCESS;
}
-
static adcli_result
create_computer_account (adcli_enroll *enroll,
LDAP *ldap)
@@ -628,22 +627,65 @@ create_computer_account (adcli_enroll *enroll,
char *vals_sAMAccountName[] = { enroll->computer_sam, NULL };
LDAPMod sAMAccountName = { LDAP_MOD_ADD, "sAMAccountName", { vals_sAMAccountName, } };
char *vals_userAccountControl[] = { "69632", NULL }; /* WORKSTATION_TRUST_ACCOUNT | DONT_EXPIRE_PASSWD */
- LDAPMod userAccountControl = { LDAP_MOD_REPLACE, "userAccountControl", { vals_userAccountControl, } };
+ LDAPMod userAccountControl = { LDAP_MOD_ADD, "userAccountControl", { vals_userAccountControl, } };
+ char *vals_supportedEncryptionTypes[] = { NULL, NULL };
+ LDAPMod encTypes = { LDAP_MOD_ADD, "msDS-supportedEncryptionTypes", { vals_supportedEncryptionTypes, } };
+ char *vals_dNSHostName[] = { enroll->host_fqdn, NULL };
+ LDAPMod dNSHostName = { LDAP_MOD_ADD, "dNSHostName", { vals_dNSHostName, } };
+ char *vals_operatingSystem[] = { enroll->os_name, NULL };
+ LDAPMod operatingSystem = { LDAP_MOD_ADD, "operatingSystem", { vals_operatingSystem, } };
+ char *vals_operatingSystemVersion[] = { enroll->os_version, NULL };
+ LDAPMod operatingSystemVersion = { LDAP_MOD_ADD, "operatingSystemVersion", { vals_operatingSystemVersion, } };
+ char *vals_operatingSystemServicePack[] = { enroll->os_service_pack, NULL };
+ LDAPMod operatingSystemServicePack = { LDAP_MOD_ADD, "operatingSystemServicePack", { vals_operatingSystemServicePack, } };
+ char *vals_userPrincipalName[] = { enroll->user_principal, NULL };
+ LDAPMod userPrincipalName = { LDAP_MOD_ADD, "userPrincipalName", { vals_userPrincipalName, }, };
+ LDAPMod servicePrincipalName = { LDAP_MOD_ADD, "servicePrincipalName", { enroll->service_principals, } };
+
+ char *val = NULL;
int ret;
+ size_t c;
+ size_t m;
- LDAPMod *mods[] = {
+ LDAPMod *all_mods[] = {
&objectClass,
&sAMAccountName,
&userAccountControl,
- NULL,
+ &encTypes,
+ &dNSHostName,
+ &operatingSystem,
+ &operatingSystemVersion,
+ &operatingSystemServicePack,
+ &userPrincipalName,
+ &servicePrincipalName,
+ NULL
};
+ size_t mods_count = sizeof (all_mods) / sizeof (LDAPMod *);
+ LDAPMod *mods[mods_count];
+
if (adcli_enroll_get_trusted_for_delegation (enroll)) {
vals_userAccountControl[0] = "593920"; /* WORKSTATION_TRUST_ACCOUNT | DONT_EXPIRE_PASSWD | TRUSTED_FOR_DELEGATION */
}
+ ret = calculate_enctypes (enroll, &val);
+ if (ret != ADCLI_SUCCESS) {
+ return ret;
+ }
+ vals_supportedEncryptionTypes[0] = val;
+
+ m = 0;
+ for (c = 0; c < mods_count - 1; c++) {
+ /* Skip empty LDAP sttributes */
+ if (all_mods[c]->mod_vals.modv_strvals[0] != NULL) {
+ mods[m++] = all_mods[c];
+ }
+ }
+ mods[m] = NULL;
+
ret = ldap_add_ext_s (ldap, enroll->computer_dn, mods, NULL, NULL);
+ free (val);
/*
* Hand to head. This is really dumb... AD returns
--
2.14.4

View file

@ -1,288 +0,0 @@
From 4208646609da9b25b70c21f5f39c92fabbd59dfc Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 14 Jun 2018 16:48:22 +0200
Subject: [PATCH 21/23] util: add _adcli_strv_remove_unsorted
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1547014
---
library/adprivate.h | 4 ++
library/adutil.c | 21 ++++++++
library/seq.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++++---
library/seq.h | 12 +++++
4 files changed, 179 insertions(+), 7 deletions(-)
diff --git a/library/adprivate.h b/library/adprivate.h
index 7485249..bc9df6d 100644
--- a/library/adprivate.h
+++ b/library/adprivate.h
@@ -111,6 +111,10 @@ char ** _adcli_strv_add (char **strv,
char *string,
int *length) GNUC_WARN_UNUSED;
+void _adcli_strv_remove_unsorted (char **strv,
+ const char *string,
+ int *length);
+
void _adcli_strv_free (char **strv);
int _adcli_strv_has (char **strv,
diff --git a/library/adutil.c b/library/adutil.c
index a27bd68..6334b52 100644
--- a/library/adutil.c
+++ b/library/adutil.c
@@ -221,6 +221,27 @@ _adcli_strv_add (char **strv,
return seq_push (strv, length, string);
}
+#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
+
+void
+_adcli_strv_remove_unsorted (char **strv,
+ const char *string,
+ int *length)
+{
+ int len;
+
+ return_if_fail (string != NULL);
+
+ if (!length) {
+ len = seq_count (strv);
+ length = &len;
+ }
+
+ return seq_remove_unsorted (strv, length, discard_const (string),
+ (seq_compar)strcasecmp, free);
+}
+
+
int
_adcli_strv_has (char **strv,
const char *str)
diff --git a/library/seq.c b/library/seq.c
index 627dcaf..8e7475d 100644
--- a/library/seq.c
+++ b/library/seq.c
@@ -111,6 +111,24 @@ seq_push (seq_voidp sequence,
return seq;
}
+static int
+linear_search (void **seq,
+ int low,
+ int high,
+ void *match,
+ seq_compar compar)
+{
+ int at;
+
+ for (at = low; at < high; at++) {
+ if (compar (match, seq[at]) == 0) {
+ break;
+ }
+ }
+
+ return at;
+}
+
static int
binary_search (void **seq,
int low,
@@ -171,12 +189,13 @@ seq_insert (seq_voidp sequence,
return seq;
}
-void
-seq_remove (seq_voidp sequence,
- int *length,
- void *match,
- seq_compar compar,
- seq_destroy destroy)
+static void
+seq_remove_int (seq_voidp sequence,
+ int *length,
+ void *match,
+ seq_search search,
+ seq_compar compar,
+ seq_destroy destroy)
{
void **seq = sequence;
int at;
@@ -187,7 +206,7 @@ seq_remove (seq_voidp sequence,
assert (match != NULL);
len = *length;
- at = binary_search (seq, 0, len, match, compar);
+ at = search (seq, 0, len, match, compar);
/* We have a matching value */
if (at < len && compar (match, seq[at]) == 0) {
@@ -201,6 +220,26 @@ seq_remove (seq_voidp sequence,
*length = len;
}
+void
+seq_remove (seq_voidp sequence,
+ int *length,
+ void *match,
+ seq_compar compar,
+ seq_destroy destroy)
+{
+ return seq_remove_int (sequence, length, match, binary_search, compar, destroy);
+}
+
+void
+seq_remove_unsorted (seq_voidp sequence,
+ int *length,
+ void *match,
+ seq_compar compar,
+ seq_destroy destroy)
+{
+ return seq_remove_int (sequence, length, match, linear_search, compar, destroy);
+}
+
void
seq_filter (seq_voidp sequence,
int *length,
@@ -430,6 +469,99 @@ test_remove (void)
seq_free (seq, NULL);
}
+static void
+test_remove_unsorted (void)
+{
+ void **seq = NULL;
+ int len = 0;
+
+ seq = seq_push (seq, &len, "3");
+ seq = seq_push (seq, &len, "5");
+ seq = seq_push (seq, &len, "1");
+ seq = seq_push (seq, &len, "4");
+ seq = seq_push (seq, &len, "2");
+
+ assert_str_eq (seq[0], "3");
+ assert_str_eq (seq[1], "5");
+ assert_str_eq (seq[2], "1");
+ assert_str_eq (seq[3], "4");
+ assert_str_eq (seq[4], "2");
+ assert (seq[5] == NULL);
+ assert_num_eq (len, 5);
+
+ seq_remove_unsorted (seq, &len, "3", (seq_compar)strcmp, NULL);
+ seq_remove_unsorted (seq, &len, "2", (seq_compar)strcmp, NULL);
+
+ assert_str_eq (seq[0], "5");
+ assert_str_eq (seq[1], "1");
+ assert_str_eq (seq[2], "4");
+ assert (seq[3] == NULL);
+ assert_num_eq (len, 3);
+
+ seq_free (seq, NULL);
+}
+
+static void
+test_remove_first (void)
+{
+ void **seq = NULL;
+ int len = 0;
+
+ seq = seq_insert (seq, &len, "3", (seq_compar)strcmp, NULL);
+ seq = seq_insert (seq, &len, "5", (seq_compar)strcmp, NULL);
+ seq = seq_insert (seq, &len, "1", (seq_compar)strcmp, NULL);
+ seq = seq_insert (seq, &len, "4", (seq_compar)strcmp, NULL);
+ seq = seq_insert (seq, &len, "2", (seq_compar)strcmp, NULL);
+
+ assert_str_eq (seq[0], "1");
+ assert_str_eq (seq[1], "2");
+ assert_str_eq (seq[2], "3");
+ assert_str_eq (seq[3], "4");
+ assert_str_eq (seq[4], "5");
+ assert (seq[5] == NULL);
+ assert_num_eq (len, 5);
+
+ seq_remove (seq, &len, "1", (seq_compar)strcmp, NULL);
+
+ assert_str_eq (seq[0], "2");
+ assert_str_eq (seq[1], "3");
+ assert_str_eq (seq[2], "4");
+ assert_str_eq (seq[3], "5");
+ assert (seq[4] == NULL);
+ assert_num_eq (len, 4);
+
+ seq_free (seq, NULL);
+}
+
+static void
+test_remove_last (void)
+{
+ void **seq = NULL;
+ int len = 0;
+
+ seq = seq_insert (seq, &len, "3", (seq_compar)strcmp, NULL);
+ seq = seq_insert (seq, &len, "1", (seq_compar)strcmp, NULL);
+ seq = seq_insert (seq, &len, "4", (seq_compar)strcmp, NULL);
+ seq = seq_insert (seq, &len, "2", (seq_compar)strcmp, NULL);
+
+ assert_str_eq (seq[0], "1");
+ assert_str_eq (seq[1], "2");
+ assert_str_eq (seq[2], "3");
+ assert_str_eq (seq[3], "4");
+ assert (seq[4] == NULL);
+ assert_num_eq (len, 4);
+
+ seq_remove (seq, &len, "4", (seq_compar)strcmp, NULL);
+
+ assert_str_eq (seq[0], "1");
+ assert_str_eq (seq[1], "2");
+ assert_str_eq (seq[2], "3");
+ assert (seq[3] == NULL);
+ assert_num_eq (len, 3);
+
+ seq_free (seq, NULL);
+}
+
static int
compar_even (void *match,
void *value)
@@ -631,6 +763,9 @@ main (int argc,
test_func (test_insert, "/seq/insert");
test_func (test_insert_destroys, "/seq/insert_destroys");
test_func (test_remove, "/seq/remove");
+ test_func (test_remove_unsorted, "/seq/remove_unsorted");
+ test_func (test_remove_first, "/seq/remove_first");
+ test_func (test_remove_last, "/seq/remove_last");
test_func (test_remove_destroys, "/seq/remove_destroys");
test_func (test_filter, "/seq/filter");
test_func (test_filter_null, "/seq/filter_null");
diff --git a/library/seq.h b/library/seq.h
index 694965b..5d48848 100644
--- a/library/seq.h
+++ b/library/seq.h
@@ -44,6 +44,12 @@ typedef void * (* seq_copy) (void *value);
typedef void (* seq_destroy) (void *value);
+typedef int (* seq_search) (void **seq,
+ int low,
+ int high,
+ void *match,
+ seq_compar compar);
+
seq_voidp seq_push (seq_voidp seq,
int *length,
void *value) WARN_UNUSED;
@@ -62,6 +68,12 @@ void seq_remove (seq_voidp seq,
seq_compar compar,
seq_destroy destroy);
+void seq_remove_unsorted (seq_voidp seq,
+ int *length,
+ void *match,
+ seq_compar compar,
+ seq_destroy destroy);
+
seq_voidp seq_lookup (seq_voidp seq,
int *length,
void *match,
--
2.14.4

View file

@ -1,360 +0,0 @@
From ee71c4c0614a504b4472bf64a24fc3c18c6b9987 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 14 Jun 2018 16:49:26 +0200
Subject: [PATCH 22/23] Add add-service-principal and remove-service-principal
options
Currently it is only possible to specific a service name for service
principals but not to set the full service principal. This is e.g.
needed if there is a service running on a host which should be reachable
by a different DNS name as well.
With this patch service principal can be added and removed by specifying
the full name.
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1547014
---
doc/adcli.xml | 21 ++++++++
library/adenroll.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++--
library/adenroll.h | 8 +++
library/adldap.c | 16 ++++--
tools/computer.c | 13 +++++
5 files changed, 189 insertions(+), 8 deletions(-)
diff --git a/doc/adcli.xml b/doc/adcli.xml
index b246190..83b6981 100644
--- a/doc/adcli.xml
+++ b/doc/adcli.xml
@@ -290,6 +290,14 @@ Password for Administrator:
not allow that Kerberos tickets can be forwarded to the
host.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--add-service-principal=<parameter>service/hostname</parameter></option></term>
+ <listitem><para>Add a service principal name. In
+ contrast to the <option>--service-name</option> the
+ hostname part can be specified as well in case the
+ service should be accessible with a different host
+ name as well.</para></listitem>
+ </varlistentry>
<varlistentry>
<term><option>--show-details</option></term>
<listitem><para>After a successful join print out information
@@ -416,6 +424,19 @@ $ adcli update --login-ccache=/tmp/krbcc_123
not allow that Kerberos tickets can be forwarded to the
host.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--add-service-principal=<parameter>service/hostname</parameter></option></term>
+ <listitem><para>Add a service principal name. In
+ contrast to the <option>--service-name</option> the
+ hostname part can be specified as well in case the
+ service should be accessible with a different host
+ name as well.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>--remove-service-principal=<parameter>service/hostname</parameter></option></term>
+ <listitem><para>Remove a service principal name from
+ the keytab and the AD host object.</para></listitem>
+ </varlistentry>
<varlistentry>
<term><option>--show-details</option></term>
<listitem><para>After a successful join print out information
diff --git a/library/adenroll.c b/library/adenroll.c
index b508caf..c4ba537 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -95,6 +95,9 @@ struct _adcli_enroll {
char **service_principals;
int service_principals_explicit;
+ char **service_principals_to_add;
+ char **service_principals_to_remove;
+
char *user_principal;
int user_princpal_generate;
@@ -332,6 +335,43 @@ add_service_names_to_service_principals (adcli_enroll *enroll)
return ADCLI_SUCCESS;
}
+static adcli_result
+add_and_remove_service_principals (adcli_enroll *enroll)
+{
+ int length = 0;
+ size_t c;
+ const char **list;
+
+ if (enroll->service_principals != NULL) {
+ length = seq_count (enroll->service_principals);
+ }
+
+ list = adcli_enroll_get_service_principals_to_add (enroll);
+ if (list != NULL) {
+ for (c = 0; list[c] != NULL; c++) {
+ enroll->service_principals = _adcli_strv_add (enroll->service_principals,
+ strdup (list[c]),
+ &length);
+ if (enroll->service_principals == NULL) {
+ return ADCLI_ERR_UNEXPECTED;
+ }
+ }
+ }
+
+ list = adcli_enroll_get_service_principals_to_remove (enroll);
+ if (list != NULL) {
+ for (c = 0; list[c] != NULL; c++) {
+ /* enroll->service_principals typically refects the
+ * order of the principal in the keytabm so it is not
+ * ordered. */
+ _adcli_strv_remove_unsorted (enroll->service_principals,
+ list[c], &length);
+ }
+ }
+
+ return ADCLI_SUCCESS;
+}
+
static adcli_result
ensure_service_principals (adcli_result res,
adcli_enroll *enroll)
@@ -343,10 +383,14 @@ ensure_service_principals (adcli_result res,
if (!enroll->service_principals) {
assert (enroll->service_names != NULL);
- return add_service_names_to_service_principals (enroll);
+ res = add_service_names_to_service_principals (enroll);
}
- return ADCLI_SUCCESS;
+ if (res == ADCLI_SUCCESS) {
+ res = add_and_remove_service_principals (enroll);
+ }
+
+ return res;
}
static adcli_result
@@ -1593,6 +1637,39 @@ free_principal_salts (krb5_context k5,
free (salts);
}
+static adcli_result
+remove_principal_from_keytab (adcli_enroll *enroll,
+ krb5_context k5,
+ const char *principal_name)
+{
+ krb5_error_code code;
+ krb5_principal principal;
+ match_principal_kvno closure;
+
+ code = krb5_parse_name (k5, principal_name, &principal);
+ if (code != 0) {
+ _adcli_err ("Couldn't parse principal: %s: %s",
+ principal_name, krb5_get_error_message (k5, code));
+ return ADCLI_ERR_FAIL;
+ }
+
+ closure.kvno = enroll->kvno;
+ closure.principal = principal;
+ closure.matched = 0;
+
+ code = _adcli_krb5_keytab_clear (k5, enroll->keytab,
+ match_principal_and_kvno, &closure);
+ krb5_free_principal (k5, principal);
+
+ if (code != 0) {
+ _adcli_err ("Couldn't update keytab: %s: %s",
+ enroll->keytab_name, krb5_get_error_message (k5, code));
+ return ADCLI_ERR_FAIL;
+ }
+
+ return ADCLI_SUCCESS;
+}
+
static adcli_result
add_principal_to_keytab (adcli_enroll *enroll,
krb5_context k5,
@@ -1702,6 +1779,17 @@ update_keytab_for_principals (adcli_enroll *enroll,
return res;
}
+ if (enroll->service_principals_to_remove != NULL) {
+ for (i = 0; enroll->service_principals_to_remove[i] != NULL; i++) {
+ res = remove_principal_from_keytab (enroll, k5,
+ enroll->service_principals_to_remove[i]);
+ if (res != ADCLI_SUCCESS) {
+ _adcli_warn ("Failed to remove %s from keytab.",
+ enroll->service_principals_to_remove[i]);
+ }
+ }
+ }
+
return ADCLI_SUCCESS;
}
@@ -2029,8 +2117,11 @@ adcli_enroll_update (adcli_enroll *enroll,
if (_adcli_check_nt_time_string_lifetime (value,
adcli_enroll_get_computer_password_lifetime (enroll))) {
/* Do not update keytab if neither new service principals have
- * to be added nor the user principal has to be changed. */
- if (enroll->service_names == NULL && (enroll->user_principal == NULL || enroll->user_princpal_generate)) {
+ * to be added or deleted nor the user principal has to be changed. */
+ if (enroll->service_names == NULL
+ && (enroll->user_principal == NULL || enroll->user_princpal_generate)
+ && enroll->service_principals_to_add == NULL
+ && enroll->service_principals_to_remove == NULL) {
flags |= ADCLI_ENROLL_NO_KEYTAB;
}
flags |= ADCLI_ENROLL_PASSWORD_VALID;
@@ -2581,3 +2672,43 @@ adcli_enroll_set_trusted_for_delegation (adcli_enroll *enroll,
enroll->trusted_for_delegation = value;
enroll->trusted_for_delegation_explicit = 1;
}
+
+const char **
+adcli_enroll_get_service_principals_to_add (adcli_enroll *enroll)
+{
+ return_val_if_fail (enroll != NULL, NULL);
+
+ return (const char **)enroll->service_principals_to_add;
+}
+
+void
+adcli_enroll_add_service_principal_to_add (adcli_enroll *enroll,
+ const char *value)
+{
+ return_if_fail (enroll != NULL);
+ return_if_fail (value != NULL);
+
+ enroll->service_principals_to_add = _adcli_strv_add (enroll->service_principals_to_add,
+ strdup (value), NULL);
+ return_if_fail (enroll->service_principals_to_add != NULL);
+}
+
+const char **
+adcli_enroll_get_service_principals_to_remove (adcli_enroll *enroll)
+{
+ return_val_if_fail (enroll != NULL, NULL);
+
+ return (const char **)enroll->service_principals_to_remove;
+}
+
+void
+adcli_enroll_add_service_principal_to_remove (adcli_enroll *enroll,
+ const char *value)
+{
+ return_if_fail (enroll != NULL);
+ return_if_fail (value != NULL);
+
+ enroll->service_principals_to_remove = _adcli_strv_add (enroll->service_principals_to_remove,
+ strdup (value), NULL);
+ return_if_fail (enroll->service_principals_to_remove != NULL);
+}
diff --git a/library/adenroll.h b/library/adenroll.h
index be2ca18..f87dffa 100644
--- a/library/adenroll.h
+++ b/library/adenroll.h
@@ -98,6 +98,14 @@ const char ** adcli_enroll_get_service_principals (adcli_enroll *enroll);
void adcli_enroll_set_service_principals (adcli_enroll *enroll,
const char **value);
+const char ** adcli_enroll_get_service_principals_to_add (adcli_enroll *enroll);
+void adcli_enroll_add_service_principal_to_add (adcli_enroll *enroll,
+ const char *value);
+
+const char ** adcli_enroll_get_service_principals_to_remove (adcli_enroll *enroll);
+void adcli_enroll_add_service_principal_to_remove (adcli_enroll *enroll,
+ const char *value);
+
const char * adcli_enroll_get_user_principal (adcli_enroll *enroll);
void adcli_enroll_set_user_principal (adcli_enroll *enroll,
diff --git a/library/adldap.c b/library/adldap.c
index 07dc373..d93efb7 100644
--- a/library/adldap.c
+++ b/library/adldap.c
@@ -210,16 +210,24 @@ _adcli_ldap_have_in_mod (LDAPMod *mod,
struct berval *vals;
struct berval **pvals;
int count = 0;
+ int count_have = 0;
int i;
int ret;
- /* Already in berval format, just compare */
- if (mod->mod_op & LDAP_MOD_BVALUES)
- return _adcli_ldap_have_vals (mod->mod_vals.modv_bvals, have);
-
/* Count number of values */
for (i = 0; mod->mod_vals.modv_strvals[i] != 0; i++)
count++;
+ for (i = 0; have[i] != 0; i++)
+ count_have++;
+
+ /* If numbers different something has to be added or removed */
+ if (count != count_have) {
+ return 0;
+ }
+
+ /* Already in berval format, just compare */
+ if (mod->mod_op & LDAP_MOD_BVALUES)
+ return _adcli_ldap_have_vals (mod->mod_vals.modv_bvals, have);
vals = malloc (sizeof (struct berval) * (count + 1));
pvals = malloc (sizeof (struct berval *) * (count + 1));
diff --git a/tools/computer.c b/tools/computer.c
index b905fd1..377d449 100644
--- a/tools/computer.c
+++ b/tools/computer.c
@@ -110,6 +110,8 @@ typedef enum {
opt_add_samba_data,
opt_samba_data_tool,
opt_trusted_for_delegation,
+ opt_add_service_principal,
+ opt_remove_service_principal,
} Option;
static adcli_tool_desc common_usages[] = {
@@ -138,6 +140,8 @@ static adcli_tool_desc common_usages[] = {
{ opt_computer_password_lifetime, "lifetime of the host accounts password in days", },
{ opt_trusted_for_delegation, "set/unset the TRUSTED_FOR_DELEGATION flag\n"
"in the userAccountControl attribute", },
+ { opt_add_service_principal, "add the given service principal to the account\n" },
+ { opt_remove_service_principal, "remove the given service principal from the account\n" },
{ opt_no_password, "don't prompt for or read a password" },
{ opt_prompt_password, "prompt for a password if necessary" },
{ opt_stdin_password, "read a password from stdin (until EOF) if\n"
@@ -289,6 +293,12 @@ parse_option (Option opt,
adcli_enroll_set_trusted_for_delegation (enroll, false);
}
return;
+ case opt_add_service_principal:
+ adcli_enroll_add_service_principal_to_add (enroll, optarg);
+ return;
+ case opt_remove_service_principal:
+ adcli_enroll_add_service_principal_to_remove (enroll, optarg);
+ return;
case opt_verbose:
return;
@@ -353,6 +363,7 @@ adcli_tool_computer_join (adcli_conn *conn,
{ "os-service-pack", optional_argument, NULL, opt_os_service_pack },
{ "user-principal", optional_argument, NULL, opt_user_principal },
{ "trusted-for-delegation", required_argument, NULL, opt_trusted_for_delegation },
+ { "add-service-principal", required_argument, NULL, opt_add_service_principal },
{ "show-details", no_argument, NULL, opt_show_details },
{ "show-password", no_argument, NULL, opt_show_password },
{ "add-samba-data", no_argument, NULL, opt_add_samba_data },
@@ -458,6 +469,8 @@ adcli_tool_computer_update (adcli_conn *conn,
{ "user-principal", optional_argument, NULL, opt_user_principal },
{ "computer-password-lifetime", optional_argument, NULL, opt_computer_password_lifetime },
{ "trusted-for-delegation", required_argument, NULL, opt_trusted_for_delegation },
+ { "add-service-principal", required_argument, NULL, opt_add_service_principal },
+ { "remove-service-principal", required_argument, NULL, opt_remove_service_principal },
{ "show-details", no_argument, NULL, opt_show_details },
{ "show-password", no_argument, NULL, opt_show_password },
{ "add-samba-data", no_argument, NULL, opt_add_samba_data },
--
2.14.4

View file

@ -1,32 +0,0 @@
From 026cfacabfad58ae2cebcdf6cd82d905023ea289 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 31 May 2018 17:01:36 +0200
Subject: [PATCH 23/23] adcli_conn_is_writeable: do not crash id domain_disco
is missing
Resolves https://bugzilla.redhat.com/show_bug.cgi?id=1575554
---
library/adconn.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/library/adconn.c b/library/adconn.c
index d2fb1d5..e2250e3 100644
--- a/library/adconn.c
+++ b/library/adconn.c
@@ -1567,6 +1567,11 @@ adcli_conn_server_has_capability (adcli_conn *conn,
bool adcli_conn_is_writeable (adcli_conn *conn)
{
- disco_dance_if_necessary (conn);
- return ( (conn->domain_disco->flags & ADCLI_DISCO_WRITABLE) != 0);
+ disco_dance_if_necessary (conn);
+
+ if (conn->domain_disco == NULL) {
+ return false;
+ }
+
+ return ( (conn->domain_disco->flags & ADCLI_DISCO_WRITABLE) != 0);
}
--
2.14.4

View file

@ -1,203 +0,0 @@
From 1e57862cf5d8f4f774868b3599e4a34c525ae348 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 5 Jul 2018 13:06:26 +0200
Subject: [PATCH 24/24] doc: fix typos in the adcli man page
Resolves https://bugzilla.redhat.com/show_bug.cgi?id=1440533
---
doc/adcli.xml | 44 ++++++++++++++++++++++----------------------
1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/doc/adcli.xml b/doc/adcli.xml
index 83b6981..97dec08 100644
--- a/doc/adcli.xml
+++ b/doc/adcli.xml
@@ -105,19 +105,19 @@
<varlistentry>
<term><option>-D, --domain=<parameter>domain</parameter></option></term>
<listitem><para>The domain to connect to. If a domain is
- not specified then the domain part of the local computer's
+ not specified, then the domain part of the local computer's
host name is used.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-R, --domain-realm=<parameter>REALM</parameter></option></term>
<listitem><para>Kerberos realm for the domain. If not
- specified then the upper cased domain name is
+ specified, then the upper cased domain name is
used.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-S, --domain-controller=<parameter>server</parameter></option></term>
<listitem><para>Connect to a specific domain controller.
- If not specified then an appropriate domain controller
+ If not specified, then an appropriate domain controller
is automatically discovered.</para></listitem>
</varlistentry>
<varlistentry>
@@ -134,7 +134,7 @@
<varlistentry>
<term><option>-U, --login-user=<parameter>User</parameter></option></term>
<listitem><para>Use the specified user account to
- authenticate with the domain. If not specified then
+ authenticate with the domain. If not specified, then
the name 'Administrator' will be used.</para></listitem>
</varlistentry>
<varlistentry>
@@ -181,7 +181,7 @@ $ adcli info --domain-controller=dc.domain.example.com
<para><command>adcli info</command> will output as much information as
it can about the domain. The information is designed to be both machine
and human readable. The command will exit with a non-zero exit code
- if the domain does note exist or cannot be reached.</para>
+ if the domain does not exist or cannot be reached.</para>
<para>To show domain info for a specific domain controller use the
<option>--domain-controller</option> option to specify which domain
@@ -213,35 +213,35 @@ Password for Administrator:
<varlistentry>
<term><option>-N, --computer-name=<parameter>computer</parameter></option></term>
<listitem><para>The short non-dotted name of the computer
- account that will be created in the domain. If not specified
+ account that will be created in the domain. If not specified,
then the first portion of the <option>--host-fqdn</option>
is used.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-O, --domain-ou=<parameter>OU=xxx</parameter></option></term>
<listitem><para>The full distinguished name of the OU in
- which to create the computer account. If not specified
+ which to create the computer account. If not specified,
then the computer account will be created in a default
location.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-H, --host-fqdn=<parameter>host</parameter></option></term>
<listitem><para>Override the local machine's fully qualified
- domain name. If not specified the local machine's hostname
+ domain name. If not specified, the local machine's hostname
will be retrieved via <function>gethostname()</function>.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-K, --host-keytab=<parameter>/path/to/keytab</parameter></option></term>
<listitem><para>Specify the path to the host keytab where
host credentials will be written after a successful join
- operation. If not specified the default location will be
+ operation. If not specified, the default location will be
used, usually <filename>/etc/krb5.keytab</filename>.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--login-type=<parameter>{computer|user}</parameter></option></term>
<listitem><para>Specify the type of authentication that
will be performed before creating the machine account in
- the domain. If set to 'computer' then the computer must
+ the domain. If set to 'computer', then the computer must
already have a preset account in the domain. If not
specified and none of the other <option>--login-xxx</option>
arguments have been specified, then will try both
@@ -329,7 +329,7 @@ Password for Administrator:
<term><option>--samba-data-tool=<parameter>/path/to/net</parameter></option></term>
<listitem><para>If Samba's <command>net</command>
cannot be found at
- <filename>&samba_data_tool;</filename> this option can
+ <filename>&samba_data_tool;</filename>, this option can
be used to specific an alternative location with the
help of an absolute path.</para></listitem>
</varlistentry>
@@ -351,7 +351,7 @@ Password for Administrator:
$ adcli update
</programlisting>
- <para>If used with a credential cache other attributes of the computer
+ <para>If used with a credential cache, other attributes of the computer
account can be changed as well if the principal has sufficient
privileges.</para>
@@ -367,20 +367,20 @@ $ adcli update --login-ccache=/tmp/krbcc_123
<varlistentry>
<term><option>-N, --computer-name=<parameter>computer</parameter></option></term>
<listitem><para>The short non-dotted name of the computer
- account that will be created in the domain. If not specified
+ account that will be created in the domain. If not specified,
it will be retrieved from the keytab entries.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-H, --host-fqdn=<parameter>host</parameter></option></term>
<listitem><para>The local machine's fully qualified
- domain name. If not specified the local machine's hostname
+ domain name. If not specified, the local machine's hostname
will be retrieved from the keytab entries.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-K, --host-keytab=<parameter>/path/to/keytab</parameter></option></term>
<listitem><para>Specify the path to the host keytab where
current host credentials are stored and the new ones
- will be written to. If not specified the default
+ will be written to. If not specified, the default
location will be used, usually
<filename>/etc/krb5.keytab</filename>.</para></listitem>
</varlistentry>
@@ -462,7 +462,7 @@ $ adcli update --login-ccache=/tmp/krbcc_123
<term><option>--samba-data-tool=<parameter>/path/to/net</parameter></option></term>
<listitem><para>If Samba's <command>net</command>
cannot be found at
- <filename>&samba_data_tool;</filename> this option can
+ <filename>&samba_data_tool;</filename>, this option can
be used to specific an alternative location with the
help of an absolute path.</para></listitem>
</varlistentry>
@@ -493,7 +493,7 @@ $ adcli create-user Fry --domain=domain.example.com \
<varlistentry>
<term><option>-O, --domain-ou=<parameter>OU=xxx</parameter></option></term>
<listitem><para>The full distinguished name of the OU in
- which to create the user account. If not specified
+ which to create the user account. If not specified,
then the computer account will be created in a default
location.</para></listitem>
</varlistentry>
@@ -569,7 +569,7 @@ $ adcli create-group Pilots --domain=domain.example.com \
<varlistentry>
<term><option>-O, --domain-ou=<parameter>OU=xxx</parameter></option></term>
<listitem><para>The full distinguished name of the OU in
- which to create the group. If not specified
+ which to create the group. If not specified,
then the group will be created in a default
location.</para></listitem>
</varlistentry>
@@ -649,14 +649,14 @@ Password for Administrator:
<varlistentry>
<term><option>-O, --domain-ou=<parameter>OU=xxx</parameter></option></term>
<listitem><para>The full distinguished name of the OU in
- which to create the computer accounts. If not specified
+ which to create the computer accounts. If not specified,
then the computer account will be created in a default
location.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--one-time-password</option></term>
<listitem><para>Specify a one time password to use when
- presetting the computer accounts. If not specified then
+ presetting the computer accounts. If not specified, then
a default password will be used, which allows for later
automatic joins.</para></listitem>
</varlistentry>
@@ -696,7 +696,7 @@ Password for Administrator:
<title>Reset Computer Account</title>
<para><command>adcli reset-computer</command> resets a computer account
- in the domain. If a the appropriate machine is currently joined to the
+ in the domain. If the appropriate machine is currently joined to the
domain, then its membership will be broken. The account must already
exist.</para>
@@ -716,7 +716,7 @@ $ adcli reset-computer --domain=domain.example.com host2
<term><option>--login-type=<parameter>{computer|user}</parameter></option></term>
<listitem><para>Specify the type of authentication that
will be performed before creating the machine account in
- the domain. If set to 'computer' then the computer must
+ the domain. If set to 'computer', then the computer must
already have a preset account in the domain. If not
specified and none of the other <option>--login-xxx</option>
arguments have been specified, then will try both
--
2.14.4

View file

@ -1,101 +1,107 @@
Name: adcli
Version: 0.8.2
Release: 2%{?dist}
Summary: Active Directory enrollment
License: LGPLv2+
URL: http://cgit.freedesktop.org/realmd/adcli
Source0: http://www.freedesktop.org/software/realmd/releases/adcli-%{version}.tar.gz
%global with_selinux 1
%global selinuxtype targeted
%global modulename adcli
Patch1: 0001-Remove-upper-case-only-check-when-looking-for-the-Ne.patch
Patch2: 0002-Use-strdup-if-offset-are-used.patch
Patch3: 0003-correct-spelling-of-adcli_tool_computer_delete-descr.patch
Patch4: 0004-doc-explain-that-all-credential-cache-types-are-supp.patch
Patch5: 0005-library-add-adcli_conn_is_writeable.patch
Patch6: 0006-Handle-kvno-increment-for-RODCs.patch
Patch7: 0007-Fix-memory-leak-in-test_check_nt_time_string_lifetim.patch
Patch8: 0008-library-add-_adcli_bin_sid_to_str.patch
Patch9: 0009-library-add-_adcli_call_external_program.patch
Patch10: 0010-library-add-_adcli_ldap_parse_sid.patch
Patch11: 0011-library-add-lookup_domain_sid.patch
Patch12: 0012-library-add-adcli_conn_get_domain_sid.patch
Patch13: 0013-tools-add-option-add-samba-data.patch
Patch14: 0014-tools-store-Samba-data-if-requested.patch
Patch15: 0015-make-Samba-data-tool-configurable.patch
Patch16: 0016-Add-trusted-for-delegation-option.patch
Patch17: 0017-Only-update-attributes-given-on-the-command-line.patch
Patch18: 0018-update-allow-to-add-service-names.patch
Patch19: 0019-Calculate-enctypes-in-a-separate-function.patch
Patch20: 0020-join-add-all-attributes-while-creating-computer-obje.patch
Patch21: 0021-util-add-_adcli_strv_remove_unsorted.patch
Patch22: 0022-Add-add-service-principal-and-remove-service-princip.patch
Patch23: 0023-adcli_conn_is_writeable-do-not-crash-id-domain_disco.patch
Patch24: 0024-doc-fix-typos-in-the-adcli-man-page.patch
Name: adcli
Version: 0.9.3.1
Release: 4%{?dist}
Summary: Active Directory enrollment
License: LGPL-2.1-or-later
URL: https://gitlab.freedesktop.org/realmd/adcli
Source0: https://gitlab.freedesktop.org/-/project/1196/uploads/5a1c55410c0965835b81fbd28d820d46/adcli-%{version}.tar.gz
BuildRequires: gcc
BuildRequires: intltool pkgconfig
BuildRequires: libtool
BuildRequires: gettext-devel
BuildRequires: krb5-devel
BuildRequires: openldap-devel
BuildRequires: libxslt
BuildRequires: xmlto
Patch1: 0001-enroll-fix-issues-if-default-keytab-is-used.patch
Requires: cyrus-sasl-gssapi
BuildRequires: gcc
BuildRequires: intltool pkgconfig
BuildRequires: libtool
BuildRequires: gettext-devel
BuildRequires: krb5-devel
BuildRequires: openldap-devel
BuildRequires: libxslt
BuildRequires: xmlto
BuildRequires: make
BuildRequires: libnetapi-devel
# Build dependencies for SELinux policy
%if %{with selinux}
BuildRequires: libselinux-devel
BuildRequires: selinux-policy-devel
%endif
Requires: cyrus-sasl-gssapi
Conflicts: adcli-doc < %{version}-%{release}
# adcli no longer has a library of development files
# the adcli tool itself is to be used by callers
Obsoletes: adcli-devel < 0.5
Obsoletes: adcli-devel < 0.5
%if %{with selinux}
# This ensures that the *-selinux package and all its dependencies are not
# pulled into containers and other systems that do not use SELinux. The
# policy defines types and file contexts for client and server.
Requires: (%{name}-selinux if selinux-policy-%{selinuxtype})
%endif
%description
adcli is a tool for joining an Active Directory domain using
standard LDAP and Kerberos calls.
%if %{with selinux}
# SELinux subpackage
%package selinux
Summary: The adcli SELinux policy
BuildArch: noarch
Requires: selinux-policy-%{selinuxtype}
Requires(post): selinux-policy-%{selinuxtype}
%{?selinux_requires_min}
%description selinux
Custom SELinux policy module for adcli to make sure generated Kerberos keytab
files have the right SELinux context.
%endif
%define _hardened_build 1
%prep
%setup -q
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%autosetup -p1
%build
autoreconf --force --install --verbose
%configure --disable-static --disable-silent-rules
make %{?_smp_mflags}
%configure --disable-static --disable-silent-rules \
%if 0%{?rhel}
--with-vendor-error-message='Please check\n https://red.ht/support_rhel_ad \nto get help for common issues.' \
%endif
%{nil}
%make_build
%check
make check
%install
make install DESTDIR=%{buildroot}
%make_install
find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
%post -p /sbin/ldconfig
%ldconfig_scriptlets
%postun -p /sbin/ldconfig
%if %{with selinux}
# SELinux contexts are saved so that only affected files can be
# relabeled after the policy module installation
%pre selinux
%selinux_relabel_pre -s %{selinuxtype}
%clean
%post selinux
%selinux_modules_install -s %{selinuxtype} %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp
%postun selinux
if [ $1 -eq 0 ]; then
%selinux_modules_uninstall -s %{selinuxtype} %{modulename}
fi
%posttrans selinux
%selinux_relabel_post -s %{selinuxtype}
%endif
%files
%{_sbindir}/adcli
@ -103,8 +109,9 @@ find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
%doc %{_mandir}/*/*
%package doc
Summary: adcli documentation
Summary: The adcli documentation package
BuildArch: noarch
Conflicts: adcli < %{version}-%{release}
%description doc
adcli is a tool for joining an Active Directory domain using
@ -114,7 +121,143 @@ documentation.
%files doc
%doc %{_datadir}/doc/adcli/*
%if %{with selinux}
%files selinux
%{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp
%ghost %verify(not md5 size mode mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename}
%endif
%changelog
* Fri Jan 16 2026 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.3.1-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild
* Fri Dec 19 2025 Sumit Bose <sbose@redhat.com> - 0.9.3.1-3
- Fix issue with restoring SELinux file label
* Tue Dec 16 2025 Sumit Bose <sbose@redhat.com> - 0.9.3.1-2
- Use selinux_requires_min to avoid policycoreutils-python-utils dependency
Resolves: rhbz#2422451
* Tue Dec 09 2025 Sumit Bose <sbose@redhat.com> - 0.9.3.1-1
- Rebase to latest upstream version
* Wed Jul 23 2025 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.2-10
- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild
* Thu Jan 16 2025 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.2-9
- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild
* Wed Nov 20 2024 Sumit Bose <sbose@redhat.com> - 0.9.2-8
- support for Samba's offline join and static analyser fixes
* Wed Jul 17 2024 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.2-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild
* Mon Jan 22 2024 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.2-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Fri Jan 19 2024 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.2-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Wed Oct 18 2023 Sumit Bose <sbose@redhat.com> - 0.9.2-4
- migrated to SPDX license
* Wed Jul 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.2-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
* Wed Jan 18 2023 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.2-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Thu Sep 29 2022 Sumit Bose <sbose@redhat.com> - 0.9.2-1
- Update to upstream release 0.9.2
* Wed Jul 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.1-11
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Wed Jan 19 2022 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.1-10
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Wed Jul 28 2021 Sumit Bose <sbose@redhat.com> - 0.9.1-9
- Add ns_get16() and ns_get32() to configure check
Resolves: rhbz#1984891
* Wed Jul 21 2021 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.1-8
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Mon Jun 28 2021 Sumit Bose <sbose@redhat.com> - 0.9.1-7
- Add user-passwd sub-command
- Add setattr/delattr option
* Thu Jun 03 2021 Sumit Bose <sbose@redhat.com> - 0.9.1-6
- Add fix for dont-expire-password option
* Wed Jun 02 2021 Sumit Bose <sbose@redhat.com> - 0.9.1-5
- Add dont-expire-password option and coverity fixes
* Wed Apr 07 2021 Sumit Bose <sbose@redhat.com> - 0.9.1-4
- Add macro updates for autoconf-2.71 and downstream gating
* Mon Mar 29 2021 Sumit Bose <sbose@redhat.com> - 0.9.1-3
- Add vendor error message
Resolves: rhbz#1889386
* Sat Feb 20 2021 Sumit Bose <sbose@redhat.com> - 0.9.1-2
- Add Conflicts to avoid update/downgrade issues
* Sat Feb 20 2021 Sumit Bose <sbose@redhat.com> - 0.9.1-1
- Update to upstream release 0.9.1
* Mon Jan 25 2021 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.0-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Fri Nov 13 2020 Sumit Bose <sbose@redhat.com> - 0.9.0-6
- Include the latest upstream patches with use-ldaps fixes, man page
improvements and a new sub-command to create managed service accounts
* Thu Aug 13 2020 Sumit Bose <sbose@redhat.com> - 0.9.0-5
- man page and help output fixes
* Fri Jul 31 2020 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.0-4
- Second attempt - Rebuilt for
https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Mon Jun 08 2020 Sumit Bose <sbose@redhat.com> - 0.9.0-2
- Include the latest upstream patches
* Wed Mar 18 2020 Sumit Bose <sbose@redhat.com> - 0.9.0-1
- Update to upstream release 0.9.0 and latest patches
* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 0.8.2-9
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Mon Aug 26 2019 Sumit Bose <sbose@redhat.com> - 0.8.2-8
- various fixes and improvements
Resolves: rhbz#1683745, rhbz#1738573
* Wed Jul 24 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.8.2-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Fri Jul 5 2019 Jakub Hrozek <jhrozek@redhat.com> - 0.8.2-6
- Resolves: rhbz#1727144 - adcli join fails with new krb5-libs; adcli
needs to backport patches to only use permitted
enctypes from upstream
* Tue Apr 30 2019 Sumit Bose <sbose@redhat.com> - 0.8.2-5
- addition patch for rhbz#1630187 and new ones for rhbz#1588596
Resolves: rhbz#1630187, rhbz#1588596
* Fri Mar 22 2019 Sumit Bose <sbose@redhat.com> - 0.8.2-4
- various fixes and improvements
Resolves: rhbz#1593240, rhbz#1608212, rhbz#1547014, rhbz#1547014,
rhbz#1649868, rhbz#1588596, rhbz#1642546, rhbz#1595911,
rhbz#1644311, rhbz#1337489, rhbz#1630187, rhbz#1622583
* Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.8.2-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Thu Jul 12 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.8.2-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild

6
gating.yaml Normal file
View file

@ -0,0 +1,6 @@
--- !Policy
product_versions:
- rhel-9
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier1.functional}

View file

@ -1 +1 @@
SHA512 (adcli-0.8.2.tar.gz) = a46e3f4b3c5434557a75cfe1c44c8bc7e9e7c7e240fa3a903e0095ef58505c2bcc66e80aa7b9a6bcf3284aed1d9af4068037c57cd5bd9f68a0bde34f429c44e9
SHA512 (adcli-0.9.3.1.tar.gz) = 3f501173b5344b38f33a3f65faec9e894da81b44b37bb161da103d8a29459d8807dfe566a5dd0a8c7eec466567b6cca4331c81dd70158b5478a61b03be37355d