Commit 50aad80c authored by Rocky Automation's avatar Rocky Automation 📺
Browse files

import adcli-0.8.2-12.el8

parent 86bf6c33
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 1/2] 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,4 +150,5 @@ struct _adcli_enroll {
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,
} 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
From 924465af7a4f37390bfdfdb4971e88421f52f3d9 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 f3d606e..5b0dcd5 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -856,7 +856,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
From 0353d704879f20983184f8bded4f16538d72f7cc Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 10 Mar 2021 18:12:09 +0100
Subject: [PATCH] build: add --with-vendor-error-message configure option
With the new configure option --with-vendor-error-message a packager or
a distribution can add a message if adcli returns with an error.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1889386
---
configure.ac | 15 +++++++++++++++
tools/tools.c | 6 ++++++
2 files changed, 21 insertions(+)
diff --git a/configure.ac b/configure.ac
index baa0d3b..7dfba97 100644
--- a/configure.ac
+++ b/configure.ac
@@ -123,6 +123,21 @@ if test "$sasl_invalid" = "yes"; then
AC_MSG_ERROR([Couldn't find Cyrus SASL headers])
fi
+# --------------------------------------------------------------------
+# Vendor error message
+
+AC_ARG_WITH([vendor-error-message],
+ [AS_HELP_STRING([--with-vendor-error-message=ARG],
+ [Add a vendor specific error message shown if a adcli command fails]
+ )],
+ [AS_IF([test "x$withval" != "x"],
+ [AC_DEFINE_UNQUOTED([VENDOR_MSG],
+ ["$withval"],
+ [Vendor specific error message])],
+ [AC_MSG_ERROR([--with-vendor-error-message requires an argument])]
+ )],
+ [])
+
# --------------------------------------------------------------------
# Documentation options
diff --git a/tools/tools.c b/tools/tools.c
index d0dcf98..84bbba9 100644
--- a/tools/tools.c
+++ b/tools/tools.c
@@ -538,6 +538,12 @@ main (int argc,
if (conn)
adcli_conn_unref (conn);
+#ifdef VENDOR_MSG
+ if (ret != 0) {
+ fprintf (stderr, VENDOR_MSG"\n");
+ }
+#endif
+
return ret;
}
--
2.30.2
From 13fe79c0a78028ccfe8e3d4e5ee16cfb9e143924 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 f693e58..c726093 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -3046,6 +3046,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
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/3] 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,13 +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_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
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 2/2] 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,5 +151,6 @@ struct _adcli_enroll {
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;