From dc434149d22230fab27606f59c3fb0f74318c523 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Tue, 23 Jul 2013 12:37:09 +0200 Subject: [PATCH] Don't try to set encryption types on Windows 2003 and earlier These don't have the msDS-supportedEncryptionTypes LDAP attribute, and only support a fixed set of encryption types. https://bugs.freedesktop.org/show_bug.cgi?id=67058 --- library/adconn.c | 35 +++++++++++++++++++++++++++++++++- library/adconn.h | 13 +++++++++++++ library/adenroll.c | 56 ++++++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 89 insertions(+), 15 deletions(-) diff --git a/library/adconn.c b/library/adconn.c index 1d9825f..425192c 100644 --- a/library/adconn.c +++ b/library/adconn.c @@ -72,6 +72,7 @@ struct _adcli_conn_ctx { adcli_disco *domain_disco; char *default_naming_context; char *configuration_naming_context; + char **supported_capabilities; /* Connect state */ LDAP *ldap; @@ -764,7 +765,6 @@ static adcli_result connect_and_lookup_naming (adcli_conn *conn, adcli_disco *disco) { - char *attrs[] = { "defaultNamingContext", "configurationNamingContext", NULL, }; char *canonical_host; LDAPMessage *results; adcli_result res; @@ -772,6 +772,13 @@ connect_and_lookup_naming (adcli_conn *conn, int ret; int ver; + char *attrs[] = { + "defaultNamingContext", + "configurationNamingContext", + "supportedCapabilities", + NULL + }; + assert (conn->ldap == NULL); canonical_host = disco->host_name; @@ -816,6 +823,11 @@ connect_and_lookup_naming (adcli_conn *conn, "configurationNamingContext"); } + if (conn->supported_capabilities == NULL) { + conn->supported_capabilities = _adcli_ldap_parse_values (ldap, results, + "supportedCapabilities"); + } + ldap_msgfree (results); if (conn->default_naming_context == NULL) { @@ -1113,6 +1125,7 @@ conn_free (adcli_conn *conn) free (conn->domain_short); free (conn->default_naming_context); free (conn->configuration_naming_context); + _adcli_strv_free (conn->supported_capabilities); free (conn->computer_name); free (conn->host_fqdn); @@ -1413,3 +1426,23 @@ adcli_conn_set_krb5_conf_dir (adcli_conn *conn, return_if_fail (conn != NULL); _adcli_str_set (&conn->krb5_conf_dir, value); } + +int +adcli_conn_server_has_capability (adcli_conn *conn, + const char *capability) +{ + int i; + + return_val_if_fail (conn != NULL, 0); + return_val_if_fail (capability != NULL, 0); + + if (!conn->supported_capabilities) + return 0; + + for (i = 0; conn->supported_capabilities[i] != NULL; i++) { + if (strcmp (capability, conn->supported_capabilities[i]) == 0) + return 1; + } + + return 0; +} diff --git a/library/adconn.h b/library/adconn.h index c64856e..7ef8561 100644 --- a/library/adconn.h +++ b/library/adconn.h @@ -35,6 +35,16 @@ typedef enum { ADCLI_LOGIN_USER_ACCOUNT = 1 << 2, } adcli_login_type; +#define ADCLI_CAP_OID "1.2.840.113556.1.4.800" +#define ADCLI_CAP_LDAP_INTEG_OID "1.2.840.113556.1.4.1791" +#define ADCLI_CAP_V51_OID "1.2.840.113556.1.4.1670" +#define ADCLI_CAP_ADAM_DIGEST "1.2.840.113556.1.4.1880" +#define ADCLI_CAP_ADAM_OID "1.2.840.113556.1.4.1851" +#define ADCLI_CAP_PARTIAL_SECRETS_OID "1.2.840.113556.1.4.1920" +#define ADCLI_CAP_V60_OID "1.2.840.113556.1.4.1935" +#define ADCLI_CAP_V61_R2_OID "1.2.840.113556.1.4.2080" +#define ADCLI_CAP_W8_OID "1.2.840.113556.1.4.2237" + typedef char * (* adcli_password_func) (adcli_login_type type, const char *name, int flags, @@ -126,4 +136,7 @@ const char * adcli_conn_get_krb5_conf_dir (adcli_conn *conn); void adcli_conn_set_krb5_conf_dir (adcli_conn *conn, const char *value); +int adcli_conn_server_has_capability (adcli_conn *conn, + const char *capability); + #endif /* ADCONN_H_ */ diff --git a/library/adenroll.c b/library/adenroll.c index 3f3e51a..513d0c2 100644 --- a/library/adenroll.c +++ b/library/adenroll.c @@ -42,6 +42,23 @@ #include #include +static krb5_enctype v60_later_enctypes[] = { + ENCTYPE_AES256_CTS_HMAC_SHA1_96, + ENCTYPE_AES128_CTS_HMAC_SHA1_96, + ENCTYPE_DES3_CBC_SHA1, + ENCTYPE_ARCFOUR_HMAC, + ENCTYPE_DES_CBC_MD5, + ENCTYPE_DES_CBC_CRC, + 0 +}; + +static krb5_enctype v51_earlier_enctypes[] = { + ENCTYPE_DES_CBC_CRC, + ENCTYPE_DES_CBC_MD5, + ENCTYPE_ARCFOUR_HMAC, + 0 +}; + struct _adcli_enroll { int refs; adcli_conn *conn; @@ -1018,6 +1035,7 @@ update_and_calculate_enctypes (adcli_enroll *enroll) char *vals_supportedEncryptionTypes[] = { NULL, NULL }; LDAPMod mod = { LDAP_MOD_REPLACE, "msDS-supportedEncryptionTypes", { vals_supportedEncryptionTypes, } }; LDAPMod *mods[2] = { &mod, NULL }; + int is_2008_or_later; char *new_value; LDAP *ldap; int ret; @@ -1032,15 +1050,22 @@ update_and_calculate_enctypes (adcli_enroll *enroll) * marked on it. * * If not, write our default set to the account. + * + * Note that Windows 2003 and earlier have a standard set of encryption + * types, and no msDS-supportedEncryptionTypes attribute. */ ldap = adcli_conn_get_ldap_connection (enroll->conn); return_unexpected_if_fail (ldap != NULL); - value = _adcli_ldap_parse_value (ldap, enroll->computer_attributes, "msDS-supportedEncryptionTypes"); + is_2008_or_later = adcli_conn_server_has_capability (enroll->conn, ADCLI_CAP_V60_OID); - if (!enroll->keytab_enctypes_explicit) { - if (value != NULL) { + /* In 2008 or later, use the msDS-supportedEncryptionTypes attribute */ + if (is_2008_or_later) { + value = _adcli_ldap_parse_value (ldap, enroll->computer_attributes, + "msDS-supportedEncryptionTypes"); + + if (!enroll->keytab_enctypes_explicit && value != NULL) { read_enctypes = _adcli_krb5_parse_enctypes (value); if (read_enctypes == NULL) { _adcli_warn ("Invalid or unsupported encryption types are set on " @@ -1050,6 +1075,10 @@ update_and_calculate_enctypes (adcli_enroll *enroll) enroll->keytab_enctypes = read_enctypes; } } + + /* In 2003 or earlier, standard set of enc types */ + } else { + value = _adcli_krb5_format_enctypes (v51_earlier_enctypes); } new_value = _adcli_krb5_format_enctypes (adcli_enroll_get_keytab_enctypes (enroll)); @@ -1062,6 +1091,11 @@ update_and_calculate_enctypes (adcli_enroll *enroll) if (value && strcmp (new_value, value) == 0) return ADCLI_SUCCESS; + if (!is_2008_or_later) { + _adcli_warn ("Server does not support setting encryption types"); + return ADCLI_SUCCESS; + } + vals_supportedEncryptionTypes[0] = new_value; if (filter_for_necessary_updates (enroll, ldap, enroll->computer_attributes, mods) == 0) @@ -1946,20 +1980,14 @@ adcli_enroll_set_keytab_name (adcli_enroll *enroll, krb5_enctype * adcli_enroll_get_keytab_enctypes (adcli_enroll *enroll) { - static krb5_enctype default_enctypes[] = { - ENCTYPE_AES256_CTS_HMAC_SHA1_96, - ENCTYPE_AES128_CTS_HMAC_SHA1_96, - ENCTYPE_DES3_CBC_SHA1, - ENCTYPE_ARCFOUR_HMAC, - ENCTYPE_DES_CBC_MD5, - ENCTYPE_DES_CBC_CRC, - 0 - }; - return_val_if_fail (enroll != NULL, NULL); if (enroll->keytab_enctypes) return enroll->keytab_enctypes; - return default_enctypes; + + if (adcli_conn_server_has_capability (enroll->conn, ADCLI_CAP_V60_OID)) + return v60_later_enctypes; + else + return v51_earlier_enctypes; } void -- 1.8.3.1