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