diff --git a/0001-coverity-add-missing-NULL-checks.patch b/0001-coverity-add-missing-NULL-checks.patch new file mode 100644 index 0000000..cb6c77b --- /dev/null +++ b/0001-coverity-add-missing-NULL-checks.patch @@ -0,0 +1,44 @@ +From 3c652910d05616ee12c710e2071fc884dde4eaea Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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 + diff --git a/0002-Add-dont-expire-password-option.patch b/0002-Add-dont-expire-password-option.patch new file mode 100644 index 0000000..5189f40 --- /dev/null +++ b/0002-Add-dont-expire-password-option.patch @@ -0,0 +1,229 @@ +From a78116ba0e608050f391223bad3834d48c9adf1b Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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. + ++ ++ ++ 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. ++ 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. ++ ++ + + + 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. + ++ ++ ++ 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. ++ 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. ++ ++ + + + 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 + diff --git a/adcli.spec b/adcli.spec index 34419c2..66fa6c2 100644 --- a/adcli.spec +++ b/adcli.spec @@ -1,6 +1,6 @@ Name: adcli Version: 0.9.1 -Release: 4%{?dist} +Release: 5%{?dist} Summary: Active Directory enrollment License: LGPLv2+ URL: https://gitlab.freedesktop.org/realmd/adcli @@ -8,6 +8,9 @@ Source0: https://gitlab.freedesktop.org/sbose/adcli/uploads/30880d967e79cee78919 Patch1: 0001-build-add-with-vendor-error-message-configure-option.patch 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 + BuildRequires: gcc BuildRequires: intltool pkgconfig @@ -72,6 +75,9 @@ documentation. %doc %{_datadir}/doc/adcli/* %changelog +* Wed Jun 02 2021 Sumit Bose - 0.9.1-5 +- Add dont-expire-password option and coverity fixes + * Wed Apr 07 2021 Sumit Bose - 0.9.1-4 - Add macro updates for autoconf-2.71 and downstream gating