Sync with upstream/Fedora/RHEL-8.5
Resolves: rhbz#1977168, rhbz#1977167, rhbz#1977165
This commit is contained in:
parent
478999254e
commit
972019be33
27
0001-Fix-for-dont-expire-password-option-and-join.patch
Normal file
27
0001-Fix-for-dont-expire-password-option-and-join.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From 0d8482d4ed83677424f6c9428672d225bfdfe4d9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sumit Bose <sbose@redhat.com>
|
||||||
|
Date: Thu, 3 Jun 2021 15:03:20 +0200
|
||||||
|
Subject: [PATCH] Fix for dont-expire-password option and join
|
||||||
|
|
||||||
|
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1769644
|
||||||
|
---
|
||||||
|
library/adenroll.c | 3 ++-
|
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/library/adenroll.c b/library/adenroll.c
|
||||||
|
index 7653f89..f00d179 100644
|
||||||
|
--- a/library/adenroll.c
|
||||||
|
+++ b/library/adenroll.c
|
||||||
|
@@ -859,7 +859,8 @@ create_computer_account (adcli_enroll *enroll,
|
||||||
|
uac |= UAC_TRUSTED_FOR_DELEGATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!adcli_enroll_get_dont_expire_password (enroll)) {
|
||||||
|
+ if (enroll->dont_expire_password_explicit
|
||||||
|
+ && !adcli_enroll_get_dont_expire_password (enroll)) {
|
||||||
|
uac &= ~(UAC_DONT_EXPIRE_PASSWORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
84
0001-configure-update-some-macros-for-autoconf-2.71.patch
Normal file
84
0001-configure-update-some-macros-for-autoconf-2.71.patch
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
From a8492d71a6db8565544444eef11de8c733c95ef8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sumit Bose <sbose@redhat.com>
|
||||||
|
Date: Tue, 6 Apr 2021 19:32:07 +0200
|
||||||
|
Subject: [PATCH] configure: update some macros for autoconf-2.71
|
||||||
|
|
||||||
|
---
|
||||||
|
configure.ac | 10 +++++-----
|
||||||
|
library/Makefile.am | 2 +-
|
||||||
|
tools/Makefile.am | 2 +-
|
||||||
|
3 files changed, 7 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index 7dfba97..c6ff31d 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-AC_PREREQ(2.61)
|
||||||
|
+AC_PREREQ([2.61])
|
||||||
|
|
||||||
|
AC_INIT([adcli],
|
||||||
|
[0.9.1],
|
||||||
|
@@ -33,7 +33,7 @@ LT_INIT([dlopen disable-static])
|
||||||
|
AC_PROG_CC
|
||||||
|
AC_PROG_CPP
|
||||||
|
AM_PROG_CC_C_O
|
||||||
|
-AM_PROG_LIBTOOL
|
||||||
|
+LT_INIT
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------
|
||||||
|
# Kerberos
|
||||||
|
@@ -143,7 +143,7 @@ AC_ARG_WITH([vendor-error-message],
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([whether to build documentation])
|
||||||
|
AC_ARG_ENABLE(doc,
|
||||||
|
- AC_HELP_STRING([--enable-doc],
|
||||||
|
+ AS_HELP_STRING([--enable-doc],
|
||||||
|
[Disable building documentation])
|
||||||
|
)
|
||||||
|
|
||||||
|
@@ -180,7 +180,7 @@ doc_status=$enable_doc
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([for debug mode])
|
||||||
|
AC_ARG_ENABLE(debug,
|
||||||
|
- AC_HELP_STRING([--enable-debug=no/default/yes],
|
||||||
|
+ AS_HELP_STRING([--enable-debug=no/default/yes],
|
||||||
|
[Turn on or off debugging]))
|
||||||
|
|
||||||
|
if test "$enable_debug" != "no"; then
|
||||||
|
@@ -308,7 +308,7 @@ fi
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([where is Samba's net utility])
|
||||||
|
AC_ARG_WITH([samba_data_tool],
|
||||||
|
- AC_HELP_STRING([--with-samba-data-tool=/path],
|
||||||
|
+ AS_HELP_STRING([--with-samba-data-tool=/path],
|
||||||
|
[Path to Samba's net utility]),
|
||||||
|
[],
|
||||||
|
[with_samba_data_tool=/usr/bin/net])
|
||||||
|
diff --git a/library/Makefile.am b/library/Makefile.am
|
||||||
|
index 4829555..e046606 100644
|
||||||
|
--- a/library/Makefile.am
|
||||||
|
+++ b/library/Makefile.am
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
include $(top_srcdir)/Makefile.decl
|
||||||
|
|
||||||
|
-INCLUDES = \
|
||||||
|
+AM_CPPFLAGS = \
|
||||||
|
-I$(top_srcdir) \
|
||||||
|
-DADCLI_UNSTABLE_API \
|
||||||
|
-DHOST_TRIPLET=\"$(host_triplet)\" \
|
||||||
|
diff --git a/tools/Makefile.am b/tools/Makefile.am
|
||||||
|
index 1cdf451..71ec14d 100644
|
||||||
|
--- a/tools/Makefile.am
|
||||||
|
+++ b/tools/Makefile.am
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
include $(top_srcdir)/Makefile.decl
|
||||||
|
|
||||||
|
-INCLUDES = \
|
||||||
|
+AM_CPPFLAGS = \
|
||||||
|
-I$(top_srcdir) \
|
||||||
|
-I$(top_srcdir)/library \
|
||||||
|
-DKRB5_CONFIG=\""$(sysconfdir)/krb5.conf"\" \
|
||||||
|
--
|
||||||
|
2.30.2
|
||||||
|
|
44
0001-coverity-add-missing-NULL-checks.patch
Normal file
44
0001-coverity-add-missing-NULL-checks.patch
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
From 3c652910d05616ee12c710e2071fc884dde4eaea Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sumit Bose <sbose@redhat.com>
|
||||||
|
Date: Wed, 2 Jun 2021 13:39:31 +0200
|
||||||
|
Subject: [PATCH 1/2] coverity: add missing NULL checks
|
||||||
|
|
||||||
|
---
|
||||||
|
library/adenroll.c | 2 ++
|
||||||
|
library/adldap.c | 7 +++++++
|
||||||
|
2 files changed, 9 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/library/adenroll.c b/library/adenroll.c
|
||||||
|
index 2b830a4..0f3e8b9 100644
|
||||||
|
--- a/library/adenroll.c
|
||||||
|
+++ b/library/adenroll.c
|
||||||
|
@@ -3060,6 +3060,8 @@ adcli_enroll_set_keytab_enctypes (adcli_enroll *enroll,
|
||||||
|
krb5_enctype *newval = NULL;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
+ return_if_fail (enroll != NULL);
|
||||||
|
+
|
||||||
|
if (value) {
|
||||||
|
for (len = 0; value[len] != 0; len++);
|
||||||
|
newval = malloc (sizeof (krb5_enctype) * (len + 1));
|
||||||
|
diff --git a/library/adldap.c b/library/adldap.c
|
||||||
|
index d93efb7..b86014c 100644
|
||||||
|
--- a/library/adldap.c
|
||||||
|
+++ b/library/adldap.c
|
||||||
|
@@ -231,6 +231,13 @@ _adcli_ldap_have_in_mod (LDAPMod *mod,
|
||||||
|
|
||||||
|
vals = malloc (sizeof (struct berval) * (count + 1));
|
||||||
|
pvals = malloc (sizeof (struct berval *) * (count + 1));
|
||||||
|
+ if (vals == NULL || pvals == NULL) {
|
||||||
|
+ _adcli_err ("Memory allocation failed, assuming attribute must be updated.");
|
||||||
|
+ free (vals);
|
||||||
|
+ free (pvals);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
vals[i].bv_val = mod->mod_vals.modv_strvals[i];
|
||||||
|
vals[i].bv_len = strlen (vals[i].bv_val);
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,51 @@
|
|||||||
|
From a7a40ce4f47fe40305624b6d86c135b7d27c387d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sumit Bose <sbose@redhat.com>
|
||||||
|
Date: Fri, 11 Jun 2021 12:44:36 +0200
|
||||||
|
Subject: [PATCH 1/5] library: move UAC flags to a more common header file
|
||||||
|
|
||||||
|
---
|
||||||
|
library/adenroll.c | 8 --------
|
||||||
|
library/adprivate.h | 8 ++++++++
|
||||||
|
2 files changed, 8 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/library/adenroll.c b/library/adenroll.c
|
||||||
|
index f00d179..0b1c066 100644
|
||||||
|
--- a/library/adenroll.c
|
||||||
|
+++ b/library/adenroll.c
|
||||||
|
@@ -93,14 +93,6 @@ static char *default_ad_ldap_attrs[] = {
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
-/* 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_ACCOUNTDISABLE 0x0002
|
||||||
|
-#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;
|
||||||
|
diff --git a/library/adprivate.h b/library/adprivate.h
|
||||||
|
index 55e6234..822f919 100644
|
||||||
|
--- a/library/adprivate.h
|
||||||
|
+++ b/library/adprivate.h
|
||||||
|
@@ -39,6 +39,14 @@
|
||||||
|
#define HOST_NAME_MAX 255
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+/* 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_ACCOUNTDISABLE 0x0002
|
||||||
|
+#define UAC_WORKSTATION_TRUST_ACCOUNT 0x1000
|
||||||
|
+#define UAC_DONT_EXPIRE_PASSWORD 0x10000
|
||||||
|
+#define UAC_TRUSTED_FOR_DELEGATION 0x80000
|
||||||
|
+
|
||||||
|
/* Utilities */
|
||||||
|
|
||||||
|
#if !defined(__cplusplus) && (__GNUC__ > 2)
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
229
0002-Add-dont-expire-password-option.patch
Normal file
229
0002-Add-dont-expire-password-option.patch
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
From a78116ba0e608050f391223bad3834d48c9adf1b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sumit Bose <sbose@redhat.com>
|
||||||
|
Date: Wed, 2 Jun 2021 17:24:07 +0200
|
||||||
|
Subject: [PATCH 2/2] Add dont-expire-password option
|
||||||
|
|
||||||
|
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1769644
|
||||||
|
---
|
||||||
|
doc/adcli.xml | 28 ++++++++++++++++++++++++++++
|
||||||
|
library/adenroll.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
library/adenroll.h | 4 ++++
|
||||||
|
tools/computer.c | 12 ++++++++++++
|
||||||
|
4 files changed, 87 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/doc/adcli.xml b/doc/adcli.xml
|
||||||
|
index 8ec48d4..1ed5d3f 100644
|
||||||
|
--- a/doc/adcli.xml
|
||||||
|
+++ b/doc/adcli.xml
|
||||||
|
@@ -347,6 +347,20 @@ Password for Administrator:
|
||||||
|
not allow that Kerberos tickets can be forwarded to the
|
||||||
|
host.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><option>--dont-expire-password=<parameter>yes|no|true|false</parameter></option></term>
|
||||||
|
+ <listitem><para>Set or unset the DONT_EXPIRE_PASSWORD
|
||||||
|
+ flag in the userAccountControl attribute to indicate if
|
||||||
|
+ the machine account password should expire or not. By
|
||||||
|
+ default adcli will set this flag while joining the
|
||||||
|
+ domain which corresponds to the default behavior of
|
||||||
|
+ Windows clients.</para>
|
||||||
|
+ <para>Please note that if the password will expire
|
||||||
|
+ (--dont-expire-password=false) a renewal mechanism has
|
||||||
|
+ to be enabled on the client to not loose the
|
||||||
|
+ connectivity to AD if the password expires.</para>
|
||||||
|
+ </listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--add-service-principal=<parameter>service/hostname</parameter></option></term>
|
||||||
|
<listitem><para>Add a service principal name. In
|
||||||
|
@@ -491,6 +505,20 @@ $ adcli update --login-ccache=/tmp/krbcc_123
|
||||||
|
not allow that Kerberos tickets can be forwarded to the
|
||||||
|
host.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><option>--dont-expire-password=<parameter>yes|no|true|false</parameter></option></term>
|
||||||
|
+ <listitem><para>Set or unset the DONT_EXPIRE_PASSWORD
|
||||||
|
+ flag in the userAccountControl attribute to indicate if
|
||||||
|
+ the machine account password should expire or not. By
|
||||||
|
+ default adcli will set this flag while joining the
|
||||||
|
+ domain which corresponds to the default behavior of
|
||||||
|
+ Windows clients.</para>
|
||||||
|
+ <para>Please note that if the password will expire
|
||||||
|
+ (--dont-expire-password=false) a renewal mechanism has
|
||||||
|
+ to be enabled on the client to not loose the
|
||||||
|
+ connectivity to AD if the password expires.</para>
|
||||||
|
+ </listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--account-disable=<parameter>yes|no|true|false</parameter></option></term>
|
||||||
|
<listitem><para>Set or unset the ACCOUNTDISABLE
|
||||||
|
diff --git a/library/adenroll.c b/library/adenroll.c
|
||||||
|
index 0f3e8b9..7653f89 100644
|
||||||
|
--- a/library/adenroll.c
|
||||||
|
+++ b/library/adenroll.c
|
||||||
|
@@ -153,6 +153,8 @@ struct _adcli_enroll {
|
||||||
|
char *samba_data_tool;
|
||||||
|
bool trusted_for_delegation;
|
||||||
|
int trusted_for_delegation_explicit;
|
||||||
|
+ bool dont_expire_password;
|
||||||
|
+ int dont_expire_password_explicit;
|
||||||
|
bool account_disable;
|
||||||
|
int account_disable_explicit;
|
||||||
|
char *description;
|
||||||
|
@@ -832,6 +834,8 @@ create_computer_account (adcli_enroll *enroll,
|
||||||
|
int ret;
|
||||||
|
size_t c;
|
||||||
|
size_t m;
|
||||||
|
+ uint32_t uac = UAC_WORKSTATION_TRUST_ACCOUNT | UAC_DONT_EXPIRE_PASSWORD ;
|
||||||
|
+ char *uac_str = NULL;
|
||||||
|
|
||||||
|
LDAPMod *all_mods[] = {
|
||||||
|
&objectClass,
|
||||||
|
@@ -852,11 +856,21 @@ create_computer_account (adcli_enroll *enroll,
|
||||||
|
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 */
|
||||||
|
+ uac |= UAC_TRUSTED_FOR_DELEGATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (!adcli_enroll_get_dont_expire_password (enroll)) {
|
||||||
|
+ uac &= ~(UAC_DONT_EXPIRE_PASSWORD);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (asprintf (&uac_str, "%d", uac) < 0) {
|
||||||
|
+ return_val_if_reached (ADCLI_ERR_UNEXPECTED);
|
||||||
|
+ }
|
||||||
|
+ vals_userAccountControl[0] = uac_str;
|
||||||
|
+
|
||||||
|
ret = calculate_enctypes (enroll, &val);
|
||||||
|
if (ret != ADCLI_SUCCESS) {
|
||||||
|
+ free (uac_str);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
vals_supportedEncryptionTypes[0] = val;
|
||||||
|
@@ -871,6 +885,7 @@ create_computer_account (adcli_enroll *enroll,
|
||||||
|
mods[m] = NULL;
|
||||||
|
|
||||||
|
ret = ldap_add_ext_s (ldap, enroll->computer_dn, mods, NULL, NULL);
|
||||||
|
+ free (uac_str);
|
||||||
|
free (val);
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -1577,6 +1592,14 @@ static char *get_user_account_control (adcli_enroll *enroll)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (enroll->dont_expire_password_explicit) {
|
||||||
|
+ if (adcli_enroll_get_dont_expire_password (enroll)) {
|
||||||
|
+ uac |= UAC_DONT_EXPIRE_PASSWORD;
|
||||||
|
+ } else {
|
||||||
|
+ uac &= ~(UAC_DONT_EXPIRE_PASSWORD);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (enroll->account_disable_explicit) {
|
||||||
|
if (adcli_enroll_get_account_disable (enroll)) {
|
||||||
|
uac |= UAC_ACCOUNTDISABLE;
|
||||||
|
@@ -1627,6 +1650,7 @@ update_computer_account (adcli_enroll *enroll)
|
||||||
|
free (value);
|
||||||
|
|
||||||
|
if (res == ADCLI_SUCCESS && (enroll->trusted_for_delegation_explicit ||
|
||||||
|
+ enroll->dont_expire_password_explicit ||
|
||||||
|
enroll->account_disable_explicit)) {
|
||||||
|
char *vals_userAccountControl[] = { NULL , NULL };
|
||||||
|
LDAPMod userAccountControl = { LDAP_MOD_REPLACE, "userAccountControl", { vals_userAccountControl, } };
|
||||||
|
@@ -3208,6 +3232,24 @@ adcli_enroll_set_trusted_for_delegation (adcli_enroll *enroll,
|
||||||
|
enroll->trusted_for_delegation_explicit = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+bool
|
||||||
|
+adcli_enroll_get_dont_expire_password (adcli_enroll *enroll)
|
||||||
|
+{
|
||||||
|
+ return_val_if_fail (enroll != NULL, false);
|
||||||
|
+
|
||||||
|
+ return enroll->dont_expire_password;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+adcli_enroll_set_dont_expire_password (adcli_enroll *enroll,
|
||||||
|
+ bool value)
|
||||||
|
+{
|
||||||
|
+ return_if_fail (enroll != NULL);
|
||||||
|
+
|
||||||
|
+ enroll->dont_expire_password = value;
|
||||||
|
+ enroll->dont_expire_password_explicit = 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
bool
|
||||||
|
adcli_enroll_get_account_disable (adcli_enroll *enroll)
|
||||||
|
{
|
||||||
|
diff --git a/library/adenroll.h b/library/adenroll.h
|
||||||
|
index 8b1c1c7..34dc683 100644
|
||||||
|
--- a/library/adenroll.h
|
||||||
|
+++ b/library/adenroll.h
|
||||||
|
@@ -126,6 +126,10 @@ bool adcli_enroll_get_trusted_for_delegation (adcli_enroll *enroll
|
||||||
|
void adcli_enroll_set_trusted_for_delegation (adcli_enroll *enroll,
|
||||||
|
bool value);
|
||||||
|
|
||||||
|
+bool adcli_enroll_get_dont_expire_password (adcli_enroll *enroll);
|
||||||
|
+void adcli_enroll_set_dont_expire_password (adcli_enroll *enroll,
|
||||||
|
+ bool value);
|
||||||
|
+
|
||||||
|
bool adcli_enroll_get_account_disable (adcli_enroll *enroll);
|
||||||
|
void adcli_enroll_set_account_disable (adcli_enroll *enroll,
|
||||||
|
bool value);
|
||||||
|
diff --git a/tools/computer.c b/tools/computer.c
|
||||||
|
index 6e309d9..16a1983 100644
|
||||||
|
--- a/tools/computer.c
|
||||||
|
+++ b/tools/computer.c
|
||||||
|
@@ -110,6 +110,7 @@ typedef enum {
|
||||||
|
opt_add_samba_data,
|
||||||
|
opt_samba_data_tool,
|
||||||
|
opt_trusted_for_delegation,
|
||||||
|
+ opt_dont_expire_password,
|
||||||
|
opt_add_service_principal,
|
||||||
|
opt_remove_service_principal,
|
||||||
|
opt_description,
|
||||||
|
@@ -144,6 +145,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_dont_expire_password, "set/unset the DONT_EXPIRE_PASSWORD flag\n"
|
||||||
|
+ "in the userAccountControl attribute", },
|
||||||
|
{ opt_account_disable, "set/unset the ACCOUNTDISABLE flag\n"
|
||||||
|
"in the userAccountControl attribute", },
|
||||||
|
{ opt_add_service_principal, "add the given service principal to the account\n" },
|
||||||
|
@@ -307,6 +310,13 @@ parse_option (Option opt,
|
||||||
|
adcli_enroll_set_trusted_for_delegation (enroll, false);
|
||||||
|
}
|
||||||
|
return ADCLI_SUCCESS;
|
||||||
|
+ case opt_dont_expire_password:
|
||||||
|
+ if (strcasecmp (optarg, "true") == 0 || strcasecmp (optarg, "yes") == 0) {
|
||||||
|
+ adcli_enroll_set_dont_expire_password (enroll, true);
|
||||||
|
+ } else {
|
||||||
|
+ adcli_enroll_set_dont_expire_password (enroll, false);
|
||||||
|
+ }
|
||||||
|
+ return ADCLI_SUCCESS;
|
||||||
|
case opt_account_disable:
|
||||||
|
if (strcasecmp (optarg, "true") == 0 || strcasecmp (optarg, "yes") == 0) {
|
||||||
|
adcli_enroll_set_account_disable (enroll, true);
|
||||||
|
@@ -393,6 +403,7 @@ adcli_tool_computer_join (adcli_conn *conn,
|
||||||
|
{ "description", optional_argument, NULL, opt_description },
|
||||||
|
{ "user-principal", optional_argument, NULL, opt_user_principal },
|
||||||
|
{ "trusted-for-delegation", required_argument, NULL, opt_trusted_for_delegation },
|
||||||
|
+ { "dont-expire-password", required_argument, NULL, opt_dont_expire_password },
|
||||||
|
{ "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 },
|
||||||
|
@@ -516,6 +527,7 @@ 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 },
|
||||||
|
+ { "dont-expire-password", required_argument, NULL, opt_dont_expire_password },
|
||||||
|
{ "account-disable", required_argument, NULL, opt_account_disable },
|
||||||
|
{ "add-service-principal", required_argument, NULL, opt_add_service_principal },
|
||||||
|
{ "remove-service-principal", required_argument, NULL, opt_remove_service_principal },
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,60 @@
|
|||||||
|
From 7148ab196d0a96ede9b5ef463b0481d0fe372b21 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sumit Bose <sbose@redhat.com>
|
||||||
|
Date: Fri, 11 Jun 2021 12:46:03 +0200
|
||||||
|
Subject: [PATCH 2/5] adcli_entry: add entry_attrs with userAccountControl
|
||||||
|
attribute
|
||||||
|
|
||||||
|
---
|
||||||
|
library/adentry.c | 8 ++++++--
|
||||||
|
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/library/adentry.c b/library/adentry.c
|
||||||
|
index 1cc0518..13dcaf8 100644
|
||||||
|
--- a/library/adentry.c
|
||||||
|
+++ b/library/adentry.c
|
||||||
|
@@ -42,6 +42,7 @@ struct _adcli_entry {
|
||||||
|
char *entry_dn;
|
||||||
|
char *domain_ou;
|
||||||
|
char *entry_container;
|
||||||
|
+ LDAPMessage *entry_attrs;
|
||||||
|
};
|
||||||
|
|
||||||
|
static adcli_entry *
|
||||||
|
@@ -63,6 +64,7 @@ entry_new (adcli_conn *conn,
|
||||||
|
|
||||||
|
entry->builder = builder;
|
||||||
|
entry->object_class = object_class;
|
||||||
|
+ entry->entry_attrs = NULL;
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -82,6 +84,7 @@ entry_free (adcli_entry *entry)
|
||||||
|
free (entry->entry_container);
|
||||||
|
free (entry->entry_dn);
|
||||||
|
free (entry->domain_ou);
|
||||||
|
+ ldap_msgfree (entry->entry_attrs);
|
||||||
|
adcli_conn_unref (entry->conn);
|
||||||
|
free (entry);
|
||||||
|
}
|
||||||
|
@@ -102,7 +105,7 @@ static adcli_result
|
||||||
|
update_entry_from_domain (adcli_entry *entry,
|
||||||
|
LDAP *ldap)
|
||||||
|
{
|
||||||
|
- const char *attrs[] = { "1.1", NULL };
|
||||||
|
+ const char *attrs[] = { "userAccountControl", NULL };
|
||||||
|
LDAPMessage *results;
|
||||||
|
LDAPMessage *first;
|
||||||
|
const char *base;
|
||||||
|
@@ -139,7 +142,8 @@ update_entry_from_domain (adcli_entry *entry,
|
||||||
|
return_unexpected_if_fail (entry->entry_dn != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
- ldap_msgfree (results);
|
||||||
|
+ ldap_msgfree (entry->entry_attrs);
|
||||||
|
+ entry->entry_attrs = results;
|
||||||
|
return ADCLI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
366
0003-entry-add-passwd-user-sub-command.patch
Normal file
366
0003-entry-add-passwd-user-sub-command.patch
Normal file
@ -0,0 +1,366 @@
|
|||||||
|
From 6a673b236dfdfdf9c73cc3d2ccf3949eb1a5ddd0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sumit Bose <sbose@redhat.com>
|
||||||
|
Date: Fri, 11 Jun 2021 12:47:37 +0200
|
||||||
|
Subject: [PATCH 3/5] entry: add passwd-user sub-command
|
||||||
|
|
||||||
|
The new command allows to set or reset a user password with the help of
|
||||||
|
an account privileged to set the password.
|
||||||
|
|
||||||
|
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1952828
|
||||||
|
---
|
||||||
|
doc/adcli.xml | 20 +++++++
|
||||||
|
library/adentry.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
library/adentry.h | 3 +
|
||||||
|
tools/entry.c | 99 +++++++++++++++++++++++++++++++++
|
||||||
|
tools/tools.c | 1 +
|
||||||
|
tools/tools.h | 4 ++
|
||||||
|
6 files changed, 265 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/doc/adcli.xml b/doc/adcli.xml
|
||||||
|
index 1ed5d3f..6c36297 100644
|
||||||
|
--- a/doc/adcli.xml
|
||||||
|
+++ b/doc/adcli.xml
|
||||||
|
@@ -56,6 +56,11 @@
|
||||||
|
<arg choice="opt">--domain=domain.example.com</arg>
|
||||||
|
<arg choice="plain">user</arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
+ <cmdsynopsis>
|
||||||
|
+ <command>adcli passwd-user</command>
|
||||||
|
+ <arg choice="opt">--domain=domain.example.com</arg>
|
||||||
|
+ <arg choice="plain">user</arg>
|
||||||
|
+ </cmdsynopsis>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>adcli create-group</command>
|
||||||
|
<arg choice="opt">--domain=domain.example.com</arg>
|
||||||
|
@@ -696,6 +701,21 @@ $ adcli delete-user Fry --domain=domain.example.com
|
||||||
|
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
+<refsect1 id='passwd_user'>
|
||||||
|
+ <title>(Re)setting the password of a User with an Administrative Account</title>
|
||||||
|
+
|
||||||
|
+ <para><command>adcli passwd-user</command> sets or resets the password
|
||||||
|
+ of user account. The administrative account used for this operation
|
||||||
|
+ must have privileges to set a password.</para>
|
||||||
|
+
|
||||||
|
+<programlisting>
|
||||||
|
+$ adcli passwd-user Fry --domain=domain.example.com
|
||||||
|
+</programlisting>
|
||||||
|
+
|
||||||
|
+ <para>The various global options can be used.</para>
|
||||||
|
+
|
||||||
|
+</refsect1>
|
||||||
|
+
|
||||||
|
|
||||||
|
<refsect1 id='create_group'>
|
||||||
|
<title>Creating a Group</title>
|
||||||
|
diff --git a/library/adentry.c b/library/adentry.c
|
||||||
|
index 13dcaf8..0d9b9af 100644
|
||||||
|
--- a/library/adentry.c
|
||||||
|
+++ b/library/adentry.c
|
||||||
|
@@ -409,6 +409,144 @@ adcli_entry_delete (adcli_entry *entry)
|
||||||
|
return ADCLI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static adcli_result
|
||||||
|
+adcli_entry_ensure_enabled (adcli_entry *entry)
|
||||||
|
+{
|
||||||
|
+ adcli_result res;
|
||||||
|
+ LDAP *ldap;
|
||||||
|
+ adcli_attrs *attrs;
|
||||||
|
+ uint32_t uac = 0;
|
||||||
|
+ char *uac_str;
|
||||||
|
+ unsigned long attr_val;
|
||||||
|
+ char *end;
|
||||||
|
+
|
||||||
|
+ return_unexpected_if_fail (entry->entry_attrs != NULL);
|
||||||
|
+
|
||||||
|
+ ldap = adcli_conn_get_ldap_connection (entry->conn);
|
||||||
|
+ return_unexpected_if_fail (ldap != NULL);
|
||||||
|
+
|
||||||
|
+ uac_str = _adcli_ldap_parse_value (ldap, entry->entry_attrs,
|
||||||
|
+ "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 %s account in directory: %s, assuming 0",
|
||||||
|
+ uac_str, entry->object_class, entry->entry_dn);
|
||||||
|
+ } else {
|
||||||
|
+ uac = attr_val;
|
||||||
|
+ }
|
||||||
|
+ free (uac_str);
|
||||||
|
+ }
|
||||||
|
+ if (uac & UAC_ACCOUNTDISABLE) {
|
||||||
|
+ uac &= ~(UAC_ACCOUNTDISABLE);
|
||||||
|
+
|
||||||
|
+ if (asprintf (&uac_str, "%d", uac) < 0) {
|
||||||
|
+ _adcli_warn ("Cannot enable %s entry %s after password (re)set",
|
||||||
|
+ entry->object_class, entry->entry_dn);
|
||||||
|
+ return ADCLI_ERR_UNEXPECTED;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ attrs = adcli_attrs_new ();
|
||||||
|
+ adcli_attrs_replace (attrs, "userAccountControl", uac_str,
|
||||||
|
+ NULL);
|
||||||
|
+ res = adcli_entry_modify (entry, attrs);
|
||||||
|
+ if (res == ADCLI_SUCCESS) {
|
||||||
|
+ _adcli_info ("Enabled %s entry %s after password (re)set",
|
||||||
|
+ entry->object_class, entry->entry_dn);
|
||||||
|
+ } else {
|
||||||
|
+ _adcli_warn ("Failed to enable %s entry %s after password (re)set",
|
||||||
|
+ entry->object_class, entry->entry_dn);
|
||||||
|
+ }
|
||||||
|
+ free (uac_str);
|
||||||
|
+ adcli_attrs_free (attrs);
|
||||||
|
+ } else {
|
||||||
|
+ res = ADCLI_SUCCESS;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return res;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+adcli_result
|
||||||
|
+adcli_entry_set_passwd (adcli_entry *entry, const char *user_pwd)
|
||||||
|
+{
|
||||||
|
+ adcli_result res;
|
||||||
|
+ LDAP *ldap;
|
||||||
|
+ krb5_error_code code;
|
||||||
|
+ krb5_context k5;
|
||||||
|
+ krb5_ccache ccache;
|
||||||
|
+ krb5_data result_string = { 0, };
|
||||||
|
+ krb5_data result_code_string = { 0, };
|
||||||
|
+ int result_code;
|
||||||
|
+ char *message;
|
||||||
|
+ krb5_principal user_principal;
|
||||||
|
+
|
||||||
|
+ ldap = adcli_conn_get_ldap_connection (entry->conn);
|
||||||
|
+ return_unexpected_if_fail (ldap != NULL);
|
||||||
|
+
|
||||||
|
+ /* Find the user */
|
||||||
|
+ res = update_entry_from_domain (entry, ldap);
|
||||||
|
+ if (res != ADCLI_SUCCESS)
|
||||||
|
+ return res;
|
||||||
|
+
|
||||||
|
+ if (!entry->entry_dn) {
|
||||||
|
+ _adcli_err ("Cannot find the %s entry %s in the domain",
|
||||||
|
+ entry->object_class, entry->sam_name);
|
||||||
|
+ return ADCLI_ERR_CONFIG;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ k5 = adcli_conn_get_krb5_context (entry->conn);
|
||||||
|
+ return_unexpected_if_fail (k5 != NULL);
|
||||||
|
+
|
||||||
|
+ code = _adcli_krb5_build_principal (k5, entry->sam_name,
|
||||||
|
+ adcli_conn_get_domain_realm (entry->conn),
|
||||||
|
+ &user_principal);
|
||||||
|
+ return_unexpected_if_fail (code == 0);
|
||||||
|
+
|
||||||
|
+ ccache = adcli_conn_get_login_ccache (entry->conn);
|
||||||
|
+ return_unexpected_if_fail (ccache != NULL);
|
||||||
|
+
|
||||||
|
+ memset (&result_string, 0, sizeof (result_string));
|
||||||
|
+ memset (&result_code_string, 0, sizeof (result_code_string));
|
||||||
|
+
|
||||||
|
+ code = krb5_set_password_using_ccache (k5, ccache, user_pwd,
|
||||||
|
+ user_principal, &result_code,
|
||||||
|
+ &result_code_string, &result_string);
|
||||||
|
+
|
||||||
|
+ if (code != 0) {
|
||||||
|
+ _adcli_err ("Couldn't set password for %s account: %s: %s",
|
||||||
|
+ entry->object_class,
|
||||||
|
+ entry->sam_name, krb5_get_error_message (k5, code));
|
||||||
|
+ /* TODO: Parse out these values */
|
||||||
|
+ res = ADCLI_ERR_DIRECTORY;
|
||||||
|
+
|
||||||
|
+ } else if (result_code != 0) {
|
||||||
|
+#ifdef HAVE_KRB5_CHPW_MESSAGE
|
||||||
|
+ if (krb5_chpw_message (k5, &result_string, &message) != 0)
|
||||||
|
+ message = NULL;
|
||||||
|
+#else
|
||||||
|
+ message = NULL;
|
||||||
|
+ if (result_string.length)
|
||||||
|
+ message = _adcli_str_dupn (result_string.data, result_string.length);
|
||||||
|
+#endif
|
||||||
|
+ _adcli_err ("Cannot set %s password: %.*s%s%s",
|
||||||
|
+ entry->object_class,
|
||||||
|
+ (int)result_code_string.length, result_code_string.data,
|
||||||
|
+ message ? ": " : "", message ? message : "");
|
||||||
|
+ res = ADCLI_ERR_CREDENTIALS;
|
||||||
|
+#ifdef HAVE_KRB5_CHPW_MESSAGE
|
||||||
|
+ krb5_free_string (k5, message);
|
||||||
|
+#else
|
||||||
|
+ free (message);
|
||||||
|
+#endif
|
||||||
|
+ } else {
|
||||||
|
+ _adcli_info ("Password (re)setted for %s: %s", entry->object_class, entry->entry_dn);
|
||||||
|
+
|
||||||
|
+ res = adcli_entry_ensure_enabled (entry);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return res;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
const char *
|
||||||
|
adcli_entry_get_sam_name (adcli_entry *entry)
|
||||||
|
{
|
||||||
|
diff --git a/library/adentry.h b/library/adentry.h
|
||||||
|
index ae90689..f2382b1 100644
|
||||||
|
--- a/library/adentry.h
|
||||||
|
+++ b/library/adentry.h
|
||||||
|
@@ -49,6 +49,9 @@ adcli_result adcli_entry_modify (adcli_entry *entry,
|
||||||
|
|
||||||
|
adcli_result adcli_entry_delete (adcli_entry *entry);
|
||||||
|
|
||||||
|
+adcli_result adcli_entry_set_passwd (adcli_entry *entry,
|
||||||
|
+ const char *user_pwd);
|
||||||
|
+
|
||||||
|
const char * adcli_entry_get_domain_ou (adcli_entry *entry);
|
||||||
|
|
||||||
|
void adcli_entry_set_domain_ou (adcli_entry *entry,
|
||||||
|
diff --git a/tools/entry.c b/tools/entry.c
|
||||||
|
index 05e4313..52d2546 100644
|
||||||
|
--- a/tools/entry.c
|
||||||
|
+++ b/tools/entry.c
|
||||||
|
@@ -24,6 +24,7 @@
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "adcli.h"
|
||||||
|
+#include "adprivate.h"
|
||||||
|
#include "adattrs.h"
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
@@ -385,6 +386,104 @@ adcli_tool_user_delete (adcli_conn *conn,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int
|
||||||
|
+adcli_tool_user_passwd (adcli_conn *conn,
|
||||||
|
+ int argc,
|
||||||
|
+ char *argv[])
|
||||||
|
+{
|
||||||
|
+ adcli_result res;
|
||||||
|
+ adcli_entry *entry;
|
||||||
|
+ int opt;
|
||||||
|
+ char *user_pwd = NULL;
|
||||||
|
+
|
||||||
|
+ struct option options[] = {
|
||||||
|
+ { "domain", required_argument, NULL, opt_domain },
|
||||||
|
+ { "domain-realm", required_argument, NULL, opt_domain_realm },
|
||||||
|
+ { "domain-controller", required_argument, NULL, opt_domain_controller },
|
||||||
|
+ { "use-ldaps", no_argument, 0, opt_use_ldaps },
|
||||||
|
+ { "login-user", required_argument, NULL, opt_login_user },
|
||||||
|
+ { "login-ccache", optional_argument, NULL, opt_login_ccache },
|
||||||
|
+ { "no-password", no_argument, 0, opt_no_password },
|
||||||
|
+ { "stdin-password", no_argument, 0, opt_stdin_password },
|
||||||
|
+ { "prompt-password", no_argument, 0, opt_prompt_password },
|
||||||
|
+ { "verbose", no_argument, NULL, opt_verbose },
|
||||||
|
+ { "help", no_argument, NULL, 'h' },
|
||||||
|
+ { 0 },
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ static adcli_tool_desc usages[] = {
|
||||||
|
+ { 0, "usage: adcli passwd-user --domain=xxxx user" },
|
||||||
|
+ { 0 },
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ while ((opt = adcli_tool_getopt (argc, argv, options)) != -1) {
|
||||||
|
+ switch (opt) {
|
||||||
|
+ case 'h':
|
||||||
|
+ case '?':
|
||||||
|
+ case ':':
|
||||||
|
+ adcli_tool_usage (options, usages);
|
||||||
|
+ adcli_tool_usage (options, common_usages);
|
||||||
|
+ return opt == 'h' ? 0 : 2;
|
||||||
|
+ default:
|
||||||
|
+ res = parse_option ((Option)opt, optarg, conn);
|
||||||
|
+ if (res != ADCLI_SUCCESS) {
|
||||||
|
+ return res;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ argc -= optind;
|
||||||
|
+ argv += optind;
|
||||||
|
+
|
||||||
|
+ if (argc != 1) {
|
||||||
|
+ warnx ("specify one user name to (re)set password");
|
||||||
|
+ return 2;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ entry = adcli_entry_new_user (conn, argv[0]);
|
||||||
|
+ if (entry == NULL) {
|
||||||
|
+ warnx ("unexpected memory problems");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT);
|
||||||
|
+
|
||||||
|
+ res = adcli_conn_connect (conn);
|
||||||
|
+ if (res != ADCLI_SUCCESS) {
|
||||||
|
+ warnx ("couldn't connect to %s domain: %s",
|
||||||
|
+ adcli_conn_get_domain_name (conn),
|
||||||
|
+ adcli_get_last_error ());
|
||||||
|
+ adcli_entry_unref (entry);
|
||||||
|
+ return -res;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ user_pwd = adcli_prompt_password_func (ADCLI_LOGIN_USER_ACCOUNT,
|
||||||
|
+ adcli_entry_get_sam_name(entry),
|
||||||
|
+ 0, NULL);
|
||||||
|
+ if (user_pwd == NULL || *user_pwd == '\0') {
|
||||||
|
+ warnx ("missing password");
|
||||||
|
+ _adcli_password_free (user_pwd);
|
||||||
|
+ adcli_entry_unref (entry);
|
||||||
|
+ return 2;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ res = adcli_entry_set_passwd (entry, user_pwd);
|
||||||
|
+ _adcli_password_free (user_pwd);
|
||||||
|
+ if (res != ADCLI_SUCCESS) {
|
||||||
|
+ warnx ("(re)setting password for user %s in domain %s failed: %s",
|
||||||
|
+ adcli_entry_get_sam_name (entry),
|
||||||
|
+ adcli_conn_get_domain_name (conn),
|
||||||
|
+ adcli_get_last_error ());
|
||||||
|
+ adcli_entry_unref (entry);
|
||||||
|
+ return -res;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ adcli_entry_unref (entry);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int
|
||||||
|
adcli_tool_group_create (adcli_conn *conn,
|
||||||
|
int argc,
|
||||||
|
diff --git a/tools/tools.c b/tools/tools.c
|
||||||
|
index 84bbba9..a14b9ca 100644
|
||||||
|
--- a/tools/tools.c
|
||||||
|
+++ b/tools/tools.c
|
||||||
|
@@ -63,6 +63,7 @@ struct {
|
||||||
|
{ "create-msa", adcli_tool_computer_managed_service_account, "Create a managed service account in the given AD domain", },
|
||||||
|
{ "create-user", adcli_tool_user_create, "Create a user account", },
|
||||||
|
{ "delete-user", adcli_tool_user_delete, "Delete a user account", },
|
||||||
|
+ { "passwd-user", adcli_tool_user_passwd, "(Re)set a user password", },
|
||||||
|
{ "create-group", adcli_tool_group_create, "Create a group", },
|
||||||
|
{ "delete-group", adcli_tool_group_delete, "Delete a group", },
|
||||||
|
{ "add-member", adcli_tool_member_add, "Add users to a group", },
|
||||||
|
diff --git a/tools/tools.h b/tools/tools.h
|
||||||
|
index 82d5e4e..d38aa32 100644
|
||||||
|
--- a/tools/tools.h
|
||||||
|
+++ b/tools/tools.h
|
||||||
|
@@ -94,6 +94,10 @@ int adcli_tool_user_delete (adcli_conn *conn,
|
||||||
|
int argc,
|
||||||
|
char *argv[]);
|
||||||
|
|
||||||
|
+int adcli_tool_user_passwd (adcli_conn *conn,
|
||||||
|
+ int argc,
|
||||||
|
+ char *argv[]);
|
||||||
|
+
|
||||||
|
int adcli_tool_group_create (adcli_conn *conn,
|
||||||
|
int argc,
|
||||||
|
char *argv[]);
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
386
0004-Add-setattr-option.patch
Normal file
386
0004-Add-setattr-option.patch
Normal file
@ -0,0 +1,386 @@
|
|||||||
|
From c5b0cee2976682b4fc1aeb02636cc9f2c6dbc2a5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sumit Bose <sbose@redhat.com>
|
||||||
|
Date: Mon, 14 Jun 2021 07:54:01 +0200
|
||||||
|
Subject: [PATCH 4/5] Add setattr option
|
||||||
|
|
||||||
|
With the new option common LDAP attributes can be set.
|
||||||
|
|
||||||
|
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1690920
|
||||||
|
---
|
||||||
|
doc/adcli.xml | 34 +++++++++
|
||||||
|
library/adenroll.c | 169 ++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
library/adenroll.h | 4 ++
|
||||||
|
tools/computer.c | 10 +++
|
||||||
|
4 files changed, 216 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/doc/adcli.xml b/doc/adcli.xml
|
||||||
|
index 6c36297..8383aa7 100644
|
||||||
|
--- a/doc/adcli.xml
|
||||||
|
+++ b/doc/adcli.xml
|
||||||
|
@@ -374,6 +374,23 @@ Password for Administrator:
|
||||||
|
service should be accessible with a different host
|
||||||
|
name as well.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><option>--setattr=<parameter>name=value</parameter></option></term>
|
||||||
|
+ <listitem><para>Add the LDAP attribute
|
||||||
|
+ <option><parameter>name</parameter></option> with the
|
||||||
|
+ given <option><parameter>value</parameter></option> to
|
||||||
|
+ the new LDAP host object.
|
||||||
|
+ This option can be used multiple times to add multiple
|
||||||
|
+ different attributes. Multi-value attributes are
|
||||||
|
+ currently not supported.</para>
|
||||||
|
+ <para>Please note that the account used to join the
|
||||||
|
+ domain must have the required privileges to add the
|
||||||
|
+ given attributes. Some attributes might have
|
||||||
|
+ constraints with respect to syntax and allowed values
|
||||||
|
+ which must be met as well. Attributes managed by other
|
||||||
|
+ adcli options cannot be set with this option.</para>
|
||||||
|
+ </listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--show-details</option></term>
|
||||||
|
<listitem><para>After a successful join print out information
|
||||||
|
@@ -543,6 +560,23 @@ $ adcli update --login-ccache=/tmp/krbcc_123
|
||||||
|
<listitem><para>Remove a service principal name from
|
||||||
|
the keytab and the AD host object.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><option>--setattr=<parameter>name=value</parameter></option></term>
|
||||||
|
+ <listitem><para>Add the LDAP attribute
|
||||||
|
+ <option><parameter>name</parameter></option> with the
|
||||||
|
+ given <option><parameter>value</parameter></option> to
|
||||||
|
+ the LDAP host object.
|
||||||
|
+ This option can be used multiple times to add multiple
|
||||||
|
+ different attributes. Multi-value attributes are
|
||||||
|
+ currently not supported.</para>
|
||||||
|
+ <para>Please note that the account used to update the
|
||||||
|
+ host object must have the required privileges to modify
|
||||||
|
+ the given attributes. Some attributes might have
|
||||||
|
+ constraints with respect to syntax and allowed values
|
||||||
|
+ which must be met as well. Attributes managed by other
|
||||||
|
+ adcli options cannot be set with this option.</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 0b1c066..dd51567 100644
|
||||||
|
--- a/library/adenroll.c
|
||||||
|
+++ b/library/adenroll.c
|
||||||
|
@@ -150,6 +150,7 @@ struct _adcli_enroll {
|
||||||
|
bool account_disable;
|
||||||
|
int account_disable_explicit;
|
||||||
|
char *description;
|
||||||
|
+ char **setattr;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
@@ -795,6 +796,56 @@ calculate_enctypes (adcli_enroll *enroll, char **enctype)
|
||||||
|
return ADCLI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static LDAPMod **
|
||||||
|
+get_mods_for_attrs (adcli_enroll *enroll, int mod_op)
|
||||||
|
+{
|
||||||
|
+ size_t len;
|
||||||
|
+ size_t c;
|
||||||
|
+ char *end;
|
||||||
|
+ LDAPMod **mods = NULL;
|
||||||
|
+
|
||||||
|
+ len = _adcli_strv_len (enroll->setattr);
|
||||||
|
+ if (len == 0) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ mods = calloc (len + 1, sizeof (LDAPMod *));
|
||||||
|
+ return_val_if_fail (mods != NULL, NULL);
|
||||||
|
+
|
||||||
|
+ for (c = 0; c < len; c++) {
|
||||||
|
+ end = strchr (enroll->setattr[c], '=');
|
||||||
|
+ if (end == NULL) {
|
||||||
|
+ ldap_mods_free (mods, 1);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ mods[c] = calloc (1, sizeof (LDAPMod));
|
||||||
|
+ if (mods[c] == NULL) {
|
||||||
|
+ ldap_mods_free (mods, 1);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ mods[c]->mod_op = mod_op;
|
||||||
|
+ *end = '\0';
|
||||||
|
+ mods[c]->mod_type = strdup (enroll->setattr[c]);
|
||||||
|
+ *end = '=';
|
||||||
|
+ mods[c]->mod_values = calloc (2, sizeof (char *));
|
||||||
|
+ if (mods[c]->mod_type == NULL || mods[c]->mod_values == NULL) {
|
||||||
|
+ ldap_mods_free (mods, 1);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ mods[c]->mod_values[0] = strdup (end + 1);
|
||||||
|
+ if (mods[c]->mod_values[0] == NULL) {
|
||||||
|
+ ldap_mods_free (mods, 1);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return mods;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
static adcli_result
|
||||||
|
create_computer_account (adcli_enroll *enroll,
|
||||||
|
LDAP *ldap)
|
||||||
|
@@ -828,6 +879,7 @@ create_computer_account (adcli_enroll *enroll,
|
||||||
|
size_t m;
|
||||||
|
uint32_t uac = UAC_WORKSTATION_TRUST_ACCOUNT | UAC_DONT_EXPIRE_PASSWORD ;
|
||||||
|
char *uac_str = NULL;
|
||||||
|
+ LDAPMod **extra_mods = NULL;
|
||||||
|
|
||||||
|
LDAPMod *all_mods[] = {
|
||||||
|
&objectClass,
|
||||||
|
@@ -845,7 +897,7 @@ create_computer_account (adcli_enroll *enroll,
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t mods_count = sizeof (all_mods) / sizeof (LDAPMod *);
|
||||||
|
- LDAPMod *mods[mods_count];
|
||||||
|
+ LDAPMod **mods;
|
||||||
|
|
||||||
|
if (adcli_enroll_get_trusted_for_delegation (enroll)) {
|
||||||
|
uac |= UAC_TRUSTED_FOR_DELEGATION;
|
||||||
|
@@ -868,6 +920,17 @@ create_computer_account (adcli_enroll *enroll,
|
||||||
|
}
|
||||||
|
vals_supportedEncryptionTypes[0] = val;
|
||||||
|
|
||||||
|
+ if (enroll->setattr != NULL) {
|
||||||
|
+ extra_mods = get_mods_for_attrs (enroll, LDAP_MOD_ADD);
|
||||||
|
+ if (extra_mods == NULL) {
|
||||||
|
+ _adcli_err ("Failed to add setattr attributes, "
|
||||||
|
+ "just using defaults");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ mods = calloc (mods_count + seq_count (extra_mods) + 1, sizeof (LDAPMod *));
|
||||||
|
+ return_val_if_fail (mods != NULL, ADCLI_ERR_UNEXPECTED);
|
||||||
|
+
|
||||||
|
m = 0;
|
||||||
|
for (c = 0; c < mods_count - 1; c++) {
|
||||||
|
/* Skip empty LDAP sttributes */
|
||||||
|
@@ -875,9 +938,15 @@ create_computer_account (adcli_enroll *enroll,
|
||||||
|
mods[m++] = all_mods[c];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ for (c = 0; c < seq_count (extra_mods); c++) {
|
||||||
|
+ mods[m++] = extra_mods[c];
|
||||||
|
+ }
|
||||||
|
mods[m] = NULL;
|
||||||
|
|
||||||
|
ret = ldap_add_ext_s (ldap, enroll->computer_dn, mods, NULL, NULL);
|
||||||
|
+ ldap_mods_free (extra_mods, 1);
|
||||||
|
+ free (mods);
|
||||||
|
free (uac_str);
|
||||||
|
free (val);
|
||||||
|
|
||||||
|
@@ -1698,6 +1767,14 @@ update_computer_account (adcli_enroll *enroll)
|
||||||
|
res |= update_computer_attribute (enroll, ldap, mods);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (res == ADCLI_SUCCESS && enroll->setattr != NULL) {
|
||||||
|
+ LDAPMod **mods = get_mods_for_attrs (enroll, LDAP_MOD_REPLACE);
|
||||||
|
+ if (mods != NULL) {
|
||||||
|
+ res |= update_computer_attribute (enroll, ldap, mods);
|
||||||
|
+ ldap_mods_free (mods, 1);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (res != 0)
|
||||||
|
_adcli_info ("Updated existing computer account: %s", enroll->computer_dn);
|
||||||
|
}
|
||||||
|
@@ -2751,6 +2828,7 @@ enroll_free (adcli_enroll *enroll)
|
||||||
|
free (enroll->user_principal);
|
||||||
|
_adcli_strv_free (enroll->service_names);
|
||||||
|
_adcli_strv_free (enroll->service_principals);
|
||||||
|
+ _adcli_strv_free (enroll->setattr);
|
||||||
|
_adcli_password_free (enroll->computer_password);
|
||||||
|
|
||||||
|
adcli_enroll_set_keytab_name (enroll, NULL);
|
||||||
|
@@ -3332,6 +3410,72 @@ adcli_enroll_add_service_principal_to_remove (adcli_enroll *enroll,
|
||||||
|
return_if_fail (enroll->service_principals_to_remove != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int comp_attr_name (const char *s1, const char *s2)
|
||||||
|
+{
|
||||||
|
+ size_t c = 0;
|
||||||
|
+
|
||||||
|
+ /* empty strings cannot contain an attribute name */
|
||||||
|
+ if (s1 == NULL || s2 == NULL || *s1 == '\0' || *s2 == '\0') {
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (c = 0 ; s1[c] != '\0' && s2[c] != '\0'; c++) {
|
||||||
|
+ if (s1[c] == '=' && s2[c] == '=') {
|
||||||
|
+ return 0;
|
||||||
|
+ } else if (tolower (s1[c]) != tolower (s2[c])) {
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+adcli_result
|
||||||
|
+adcli_enroll_add_setattr (adcli_enroll *enroll, const char *value)
|
||||||
|
+{
|
||||||
|
+ char *delim;
|
||||||
|
+
|
||||||
|
+ return_val_if_fail (enroll != NULL, ADCLI_ERR_CONFIG);
|
||||||
|
+ return_val_if_fail (value != NULL, ADCLI_ERR_CONFIG);
|
||||||
|
+
|
||||||
|
+ delim = strchr (value, '=');
|
||||||
|
+ if (delim == NULL) {
|
||||||
|
+ _adcli_err ("Missing '=' in setattr option [%s]", value);
|
||||||
|
+ return ADCLI_ERR_CONFIG;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (*(delim + 1) == '\0') {
|
||||||
|
+ _adcli_err ("Missing value in setattr option [%s]", value);
|
||||||
|
+ return ADCLI_ERR_CONFIG;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *delim = '\0';
|
||||||
|
+ if (_adcli_strv_has_ex (default_ad_ldap_attrs, value, strcasecmp) == 1) {
|
||||||
|
+ _adcli_err ("Attribute [%s] cannot be set with setattr", value);
|
||||||
|
+ return ADCLI_ERR_CONFIG;
|
||||||
|
+ }
|
||||||
|
+ *delim = '=';
|
||||||
|
+
|
||||||
|
+ if (_adcli_strv_has_ex (enroll->setattr, value, comp_attr_name) == 1) {
|
||||||
|
+ _adcli_err ("Attribute [%s] already set", value);
|
||||||
|
+ return ADCLI_ERR_CONFIG;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ enroll->setattr = _adcli_strv_add (enroll->setattr, strdup (value),
|
||||||
|
+ NULL);
|
||||||
|
+ return_val_if_fail (enroll->setattr != NULL, ADCLI_ERR_CONFIG);
|
||||||
|
+
|
||||||
|
+ return ADCLI_SUCCESS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const char **
|
||||||
|
+adcli_enroll_get_setattr (adcli_enroll *enroll)
|
||||||
|
+{
|
||||||
|
+ return_val_if_fail (enroll != NULL, NULL);
|
||||||
|
+ return (const char **) enroll->setattr;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
#ifdef ADENROLL_TESTS
|
||||||
|
|
||||||
|
#include "test.h"
|
||||||
|
@@ -3401,12 +3545,35 @@ test_adcli_enroll_get_permitted_keytab_enctypes (void)
|
||||||
|
adcli_conn_unref (conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+test_comp_attr_name (void)
|
||||||
|
+{
|
||||||
|
+ assert_num_eq (1, comp_attr_name (NULL ,NULL));
|
||||||
|
+ assert_num_eq (1, comp_attr_name ("" ,NULL));
|
||||||
|
+ assert_num_eq (1, comp_attr_name ("" ,""));
|
||||||
|
+ assert_num_eq (1, comp_attr_name (NULL ,""));
|
||||||
|
+ assert_num_eq (1, comp_attr_name (NULL ,"abc=xyz"));
|
||||||
|
+ assert_num_eq (1, comp_attr_name ("" ,"abc=xyz"));
|
||||||
|
+ assert_num_eq (1, comp_attr_name ("abc=xyz", NULL));
|
||||||
|
+ assert_num_eq (1, comp_attr_name ("abc=xyz", ""));
|
||||||
|
+ assert_num_eq (1, comp_attr_name ("abc=xyz", "ab=xyz"));
|
||||||
|
+ assert_num_eq (1, comp_attr_name ("ab=xyz", "abc=xyz"));
|
||||||
|
+ assert_num_eq (1, comp_attr_name ("abcxyz", "abc=xyz"));
|
||||||
|
+ assert_num_eq (1, comp_attr_name ("abc=xyz", "abcxyz"));
|
||||||
|
+ assert_num_eq (1, comp_attr_name ("abc=xyz", "a"));
|
||||||
|
+ assert_num_eq (1, comp_attr_name ("a", "abc=xyz"));
|
||||||
|
+
|
||||||
|
+ assert_num_eq (0, comp_attr_name ("abc=xyz", "abc=xyz"));
|
||||||
|
+ assert_num_eq (0, comp_attr_name ("abc=xyz", "abc=123"));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int
|
||||||
|
main (int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
test_func (test_adcli_enroll_get_permitted_keytab_enctypes,
|
||||||
|
"/attrs/adcli_enroll_get_permitted_keytab_enctypes");
|
||||||
|
+ test_func (test_comp_attr_name, "/attrs/comp_attr_name");
|
||||||
|
return test_run (argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/library/adenroll.h b/library/adenroll.h
|
||||||
|
index 34dc683..862bb60 100644
|
||||||
|
--- a/library/adenroll.h
|
||||||
|
+++ b/library/adenroll.h
|
||||||
|
@@ -138,6 +138,10 @@ const char * adcli_enroll_get_desciption (adcli_enroll *enroll);
|
||||||
|
void adcli_enroll_set_description (adcli_enroll *enroll,
|
||||||
|
const char *value);
|
||||||
|
|
||||||
|
+const char ** adcli_enroll_get_setattr (adcli_enroll *enroll);
|
||||||
|
+adcli_result adcli_enroll_add_setattr (adcli_enroll *enroll,
|
||||||
|
+ const char *value);
|
||||||
|
+
|
||||||
|
bool adcli_enroll_get_is_service (adcli_enroll *enroll);
|
||||||
|
void adcli_enroll_set_is_service (adcli_enroll *enroll,
|
||||||
|
bool value);
|
||||||
|
diff --git a/tools/computer.c b/tools/computer.c
|
||||||
|
index 16a1983..af38894 100644
|
||||||
|
--- a/tools/computer.c
|
||||||
|
+++ b/tools/computer.c
|
||||||
|
@@ -114,6 +114,7 @@ typedef enum {
|
||||||
|
opt_add_service_principal,
|
||||||
|
opt_remove_service_principal,
|
||||||
|
opt_description,
|
||||||
|
+ opt_setattr,
|
||||||
|
opt_use_ldaps,
|
||||||
|
opt_account_disable,
|
||||||
|
} Option;
|
||||||
|
@@ -152,6 +153,7 @@ static adcli_tool_desc common_usages[] = {
|
||||||
|
{ 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_description, "add a description to the account\n" },
|
||||||
|
+ { opt_setattr, "add an attribute with a value\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"
|
||||||
|
@@ -333,6 +335,12 @@ parse_option (Option opt,
|
||||||
|
case opt_description:
|
||||||
|
adcli_enroll_set_description (enroll, optarg);
|
||||||
|
return ADCLI_SUCCESS;
|
||||||
|
+ case opt_setattr:
|
||||||
|
+ ret = adcli_enroll_add_setattr (enroll, optarg);
|
||||||
|
+ if (ret != ADCLI_SUCCESS) {
|
||||||
|
+ warnx ("parsing setattr option failed");
|
||||||
|
+ }
|
||||||
|
+ return ret;
|
||||||
|
case opt_use_ldaps:
|
||||||
|
adcli_conn_set_use_ldaps (conn, true);
|
||||||
|
return ADCLI_SUCCESS;
|
||||||
|
@@ -401,6 +409,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 },
|
||||||
|
{ "description", optional_argument, NULL, opt_description },
|
||||||
|
+ { "setattr", required_argument, NULL, opt_setattr },
|
||||||
|
{ "user-principal", optional_argument, NULL, opt_user_principal },
|
||||||
|
{ "trusted-for-delegation", required_argument, NULL, opt_trusted_for_delegation },
|
||||||
|
{ "dont-expire-password", required_argument, NULL, opt_dont_expire_password },
|
||||||
|
@@ -524,6 +533,7 @@ adcli_tool_computer_update (adcli_conn *conn,
|
||||||
|
{ "os-version", required_argument, NULL, opt_os_version },
|
||||||
|
{ "os-service-pack", optional_argument, NULL, opt_os_service_pack },
|
||||||
|
{ "description", optional_argument, NULL, opt_description },
|
||||||
|
+ { "setattr", required_argument, NULL, opt_setattr },
|
||||||
|
{ "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 },
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
192
0005-Add-delattr-option.patch
Normal file
192
0005-Add-delattr-option.patch
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
From cd5b6cdcf3e6bfc5776f2865f460f608421dfa3f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sumit Bose <sbose@redhat.com>
|
||||||
|
Date: Mon, 14 Jun 2021 08:42:21 +0200
|
||||||
|
Subject: [PATCH 5/5] Add delattr option
|
||||||
|
|
||||||
|
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1690920
|
||||||
|
---
|
||||||
|
doc/adcli.xml | 11 ++++++++
|
||||||
|
library/adenroll.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
library/adenroll.h | 4 +++
|
||||||
|
tools/computer.c | 9 +++++++
|
||||||
|
4 files changed, 90 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/doc/adcli.xml b/doc/adcli.xml
|
||||||
|
index 8383aa7..bcf4857 100644
|
||||||
|
--- a/doc/adcli.xml
|
||||||
|
+++ b/doc/adcli.xml
|
||||||
|
@@ -577,6 +577,17 @@ $ adcli update --login-ccache=/tmp/krbcc_123
|
||||||
|
adcli options cannot be set with this option.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><option>--delattr=<parameter>name</parameter></option></term>
|
||||||
|
+ <listitem><para>Remove the LDAP attribute
|
||||||
|
+ <option><parameter>name</parameter></option> from the
|
||||||
|
+ LDAP host object. This option can be used multiple
|
||||||
|
+ times to remove multiple different attributes.</para>
|
||||||
|
+ <para>Please note that the account used to update the
|
||||||
|
+ host object must have the required privileges to delete
|
||||||
|
+ the given attributes. Attributes managed by other adcli
|
||||||
|
+ options cannot be removed.</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 dd51567..9a06d52 100644
|
||||||
|
--- a/library/adenroll.c
|
||||||
|
+++ b/library/adenroll.c
|
||||||
|
@@ -151,6 +151,7 @@ struct _adcli_enroll {
|
||||||
|
int account_disable_explicit;
|
||||||
|
char *description;
|
||||||
|
char **setattr;
|
||||||
|
+ char **delattr;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
@@ -845,6 +846,39 @@ get_mods_for_attrs (adcli_enroll *enroll, int mod_op)
|
||||||
|
return mods;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static LDAPMod **
|
||||||
|
+get_del_mods_for_attrs (adcli_enroll *enroll, int mod_op)
|
||||||
|
+{
|
||||||
|
+ size_t len;
|
||||||
|
+ size_t c;
|
||||||
|
+ LDAPMod **mods = NULL;
|
||||||
|
+
|
||||||
|
+ len = _adcli_strv_len (enroll->delattr);
|
||||||
|
+ if (len == 0) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ mods = calloc (len + 1, sizeof (LDAPMod *));
|
||||||
|
+ return_val_if_fail (mods != NULL, NULL);
|
||||||
|
+
|
||||||
|
+ for (c = 0; c < len; c++) {
|
||||||
|
+ mods[c] = calloc (1, sizeof (LDAPMod));
|
||||||
|
+ if (mods[c] == NULL) {
|
||||||
|
+ ldap_mods_free (mods, 1);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ mods[c]->mod_op = mod_op;
|
||||||
|
+ mods[c]->mod_type = strdup (enroll->delattr[c]);
|
||||||
|
+ mods[c]->mod_values = NULL;
|
||||||
|
+ if (mods[c]->mod_type == NULL) {
|
||||||
|
+ ldap_mods_free (mods, 1);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return mods;
|
||||||
|
+}
|
||||||
|
|
||||||
|
static adcli_result
|
||||||
|
create_computer_account (adcli_enroll *enroll,
|
||||||
|
@@ -1775,6 +1809,14 @@ update_computer_account (adcli_enroll *enroll)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (res == ADCLI_SUCCESS && enroll->delattr != NULL) {
|
||||||
|
+ LDAPMod **mods = get_del_mods_for_attrs (enroll, LDAP_MOD_DELETE);
|
||||||
|
+ if (mods != NULL) {
|
||||||
|
+ res |= update_computer_attribute (enroll, ldap, mods);
|
||||||
|
+ ldap_mods_free (mods, 1);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (res != 0)
|
||||||
|
_adcli_info ("Updated existing computer account: %s", enroll->computer_dn);
|
||||||
|
}
|
||||||
|
@@ -3475,6 +3517,30 @@ adcli_enroll_get_setattr (adcli_enroll *enroll)
|
||||||
|
return (const char **) enroll->setattr;
|
||||||
|
}
|
||||||
|
|
||||||
|
+adcli_result
|
||||||
|
+adcli_enroll_add_delattr (adcli_enroll *enroll, const char *value)
|
||||||
|
+{
|
||||||
|
+ return_val_if_fail (enroll != NULL, ADCLI_ERR_CONFIG);
|
||||||
|
+ return_val_if_fail (value != NULL, ADCLI_ERR_CONFIG);
|
||||||
|
+
|
||||||
|
+ if (_adcli_strv_has_ex (default_ad_ldap_attrs, value, strcasecmp) == 1) {
|
||||||
|
+ _adcli_err ("Attribute [%s] cannot be removed with delattr", value);
|
||||||
|
+ return ADCLI_ERR_CONFIG;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ enroll->delattr = _adcli_strv_add (enroll->delattr, strdup (value),
|
||||||
|
+ NULL);
|
||||||
|
+ return_val_if_fail (enroll->delattr != NULL, ADCLI_ERR_CONFIG);
|
||||||
|
+
|
||||||
|
+ return ADCLI_SUCCESS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const char **
|
||||||
|
+adcli_enroll_get_delattr (adcli_enroll *enroll)
|
||||||
|
+{
|
||||||
|
+ return_val_if_fail (enroll != NULL, NULL);
|
||||||
|
+ return (const char **) enroll->delattr;
|
||||||
|
+}
|
||||||
|
|
||||||
|
#ifdef ADENROLL_TESTS
|
||||||
|
|
||||||
|
diff --git a/library/adenroll.h b/library/adenroll.h
|
||||||
|
index 862bb60..e3ada33 100644
|
||||||
|
--- a/library/adenroll.h
|
||||||
|
+++ b/library/adenroll.h
|
||||||
|
@@ -142,6 +142,10 @@ const char ** adcli_enroll_get_setattr (adcli_enroll *enroll);
|
||||||
|
adcli_result adcli_enroll_add_setattr (adcli_enroll *enroll,
|
||||||
|
const char *value);
|
||||||
|
|
||||||
|
+const char ** adcli_enroll_get_delattr (adcli_enroll *enroll);
|
||||||
|
+adcli_result adcli_enroll_add_delattr (adcli_enroll *enroll,
|
||||||
|
+ const char *value);
|
||||||
|
+
|
||||||
|
bool adcli_enroll_get_is_service (adcli_enroll *enroll);
|
||||||
|
void adcli_enroll_set_is_service (adcli_enroll *enroll,
|
||||||
|
bool value);
|
||||||
|
diff --git a/tools/computer.c b/tools/computer.c
|
||||||
|
index af38894..dffeecb 100644
|
||||||
|
--- a/tools/computer.c
|
||||||
|
+++ b/tools/computer.c
|
||||||
|
@@ -115,6 +115,7 @@ typedef enum {
|
||||||
|
opt_remove_service_principal,
|
||||||
|
opt_description,
|
||||||
|
opt_setattr,
|
||||||
|
+ opt_delattr,
|
||||||
|
opt_use_ldaps,
|
||||||
|
opt_account_disable,
|
||||||
|
} Option;
|
||||||
|
@@ -154,6 +155,7 @@ static adcli_tool_desc common_usages[] = {
|
||||||
|
{ opt_remove_service_principal, "remove the given service principal from the account\n" },
|
||||||
|
{ opt_description, "add a description to the account\n" },
|
||||||
|
{ opt_setattr, "add an attribute with a value\n" },
|
||||||
|
+ { opt_delattr, "remove an attribute\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"
|
||||||
|
@@ -341,6 +343,12 @@ parse_option (Option opt,
|
||||||
|
warnx ("parsing setattr option failed");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
+ case opt_delattr:
|
||||||
|
+ ret = adcli_enroll_add_delattr (enroll, optarg);
|
||||||
|
+ if (ret != ADCLI_SUCCESS) {
|
||||||
|
+ warnx ("parsing delattr option failed");
|
||||||
|
+ }
|
||||||
|
+ return ret;
|
||||||
|
case opt_use_ldaps:
|
||||||
|
adcli_conn_set_use_ldaps (conn, true);
|
||||||
|
return ADCLI_SUCCESS;
|
||||||
|
@@ -534,6 +542,7 @@ adcli_tool_computer_update (adcli_conn *conn,
|
||||||
|
{ "os-service-pack", optional_argument, NULL, opt_os_service_pack },
|
||||||
|
{ "description", optional_argument, NULL, opt_description },
|
||||||
|
{ "setattr", required_argument, NULL, opt_setattr },
|
||||||
|
+ { "delattr", required_argument, NULL, opt_delattr },
|
||||||
|
{ "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 },
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
23
adcli.spec
23
adcli.spec
@ -1,6 +1,6 @@
|
|||||||
Name: adcli
|
Name: adcli
|
||||||
Version: 0.9.1
|
Version: 0.9.1
|
||||||
Release: 4%{?dist}
|
Release: 5%{?dist}
|
||||||
Summary: Active Directory enrollment
|
Summary: Active Directory enrollment
|
||||||
License: LGPLv2+
|
License: LGPLv2+
|
||||||
URL: https://gitlab.freedesktop.org/realmd/adcli
|
URL: https://gitlab.freedesktop.org/realmd/adcli
|
||||||
@ -8,6 +8,23 @@ Source0: https://gitlab.freedesktop.org/sbose/adcli/uploads/30880d967e79cee78919
|
|||||||
|
|
||||||
Patch1: 0001-build-add-with-vendor-error-message-configure-option.patch
|
Patch1: 0001-build-add-with-vendor-error-message-configure-option.patch
|
||||||
|
|
||||||
|
# rhbz#1977167 - [RFE] adcli should allow to modify DONT_EXPIRE_PASSWORD
|
||||||
|
# attribute
|
||||||
|
Patch2: 0001-configure-update-some-macros-for-autoconf-2.71.patch
|
||||||
|
Patch3: 0001-coverity-add-missing-NULL-checks.patch
|
||||||
|
Patch4: 0002-Add-dont-expire-password-option.patch
|
||||||
|
Patch5: 0001-Fix-for-dont-expire-password-option-and-join.patch
|
||||||
|
|
||||||
|
# rhbz#1977168 - [RFE] Allow adcli to create AD user with password as well as
|
||||||
|
# set or reset existing user password
|
||||||
|
Patch6: 0001-library-move-UAC-flags-to-a-more-common-header-file.patch
|
||||||
|
Patch7: 0002-adcli_entry-add-entry_attrs-with-userAccountControl-.patch
|
||||||
|
Patch8: 0003-entry-add-passwd-user-sub-command.patch
|
||||||
|
|
||||||
|
# rhbz#1977165 - [RFE] add option to populate "managed by" computer attribute
|
||||||
|
Patch9: 0004-Add-setattr-option.patch
|
||||||
|
Patch10: 0005-Add-delattr-option.patch
|
||||||
|
|
||||||
BuildRequires: gcc
|
BuildRequires: gcc
|
||||||
BuildRequires: intltool pkgconfig
|
BuildRequires: intltool pkgconfig
|
||||||
BuildRequires: libtool
|
BuildRequires: libtool
|
||||||
@ -71,6 +88,10 @@ documentation.
|
|||||||
%doc %{_datadir}/doc/adcli/*
|
%doc %{_datadir}/doc/adcli/*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Jun 30 2021 Sumit Bose <sbose@redhat.com> - 0.9.1-5
|
||||||
|
- Sync with upstream/Fedora/RHEL-8.5
|
||||||
|
Resolves: rhbz#1977168, rhbz#1977167, rhbz#1977165
|
||||||
|
|
||||||
* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 0.9.1-4
|
* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 0.9.1-4
|
||||||
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
|
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user