From a9843d6918f73c2236d0083b1e8adf54ca34eb0d Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 10 Sep 2013 11:56:40 +0300 Subject: ipa-sam: report supported enctypes based on Kerberos realm configuration We store Kerberos realm configuration in cn=REALM,cn=kerberos,$SUFFIX. Along other configuration options, this container has list of default supported encryption types, in krbDefaultEncSaltTypes. Fetch krbDefaultEncSaltTypes value on ipa-sam initialization and convert discovered list to the mask of supported encryption types according to security.idl from Samba: typedef [public,bitmap32bit] bitmap { KERB_ENCTYPE_DES_CBC_CRC = 0x00000001, KERB_ENCTYPE_DES_CBC_MD5 = 0x00000002, KERB_ENCTYPE_RC4_HMAC_MD5 = 0x00000004, KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96 = 0x00000008, KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96 = 0x00000010 } kerb_EncTypes; Part of https://fedorahosted.org/freeipa/ticket/3898 --- daemons/ipa-sam/ipa_sam.c | 129 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 117 insertions(+), 12 deletions(-) (limited to 'daemons') diff --git a/daemons/ipa-sam/ipa_sam.c b/daemons/ipa-sam/ipa_sam.c index b4d1a32c..a535c0f6 100644 --- a/daemons/ipa-sam/ipa_sam.c +++ b/daemons/ipa-sam/ipa_sam.c @@ -170,6 +170,7 @@ struct ipasam_privates { char *server_princ; char *client_princ; struct sss_idmap_ctx *idmap_ctx; + uint32_t supported_enctypes; }; @@ -2062,11 +2063,7 @@ static bool fill_pdb_trusted_domain(TALLOC_CTX *mem_ctx, return false; } if (*td->supported_enc_type == 0) { - *td->supported_enc_type = KERB_ENCTYPE_DES_CBC_CRC | - KERB_ENCTYPE_DES_CBC_MD5 | - KERB_ENCTYPE_RC4_HMAC_MD5 | - KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96 | - KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96; + *td->supported_enc_type = ldap_state->ipasam_privates->supported_enctypes; } if (!smbldap_talloc_single_blob(td, priv2ld(ldap_state), entry, @@ -2333,12 +2330,7 @@ static NTSTATUS ipasam_set_trusted_domain(struct pdb_methods *methods, goto done; } - enctypes = KERB_ENCTYPE_DES_CBC_CRC | - KERB_ENCTYPE_DES_CBC_MD5 | - KERB_ENCTYPE_RC4_HMAC_MD5 | - KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96 | - KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96; - + enctypes = ldap_state->ipasam_privates->supported_enctypes; if (td->supported_enc_type != NULL) { enctypes = *td->supported_enc_type; } @@ -3606,6 +3598,106 @@ static NTSTATUS ipasam_get_domain_name(struct ldapsam_privates *ldap_state, return NT_STATUS_OK; } +static NTSTATUS ipasam_get_enctypes(struct ldapsam_privates *ldap_state, + TALLOC_CTX *mem_ctx, + uint32_t *enctypes) +{ + int ret; + LDAPMessage *result; + LDAPMessage *entry = NULL; + int count, i; + char **enctype_list, *dn; + krb5_enctype enctype; + krb5_error_code err; + struct smbldap_state *smbldap_state = ldap_state->smbldap_state; + const char *attr_list[] = { + "krbDefaultEncSaltTypes", + NULL + }; + + dn = talloc_asprintf(mem_ctx, "cn=%s,cn=kerberos,%s", + ldap_state->ipasam_privates->realm, + ldap_state->ipasam_privates->base_dn); + + if (dn == NULL) { + DEBUG(1, ("Failed to construct DN to the realm's kerberos container\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + ret = smbldap_search(smbldap_state, dn, LDAP_SCOPE_BASE, + "objectclass=krbrealmcontainer", attr_list, 0, + &result); + if (ret != LDAP_SUCCESS) { + DEBUG(1, ("Failed to get kerberos realm encryption types: %s\n", + ldap_err2string (ret))); + talloc_free(dn); + return NT_STATUS_UNSUCCESSFUL; + } + + count = ldap_count_entries(smbldap_state->ldap_struct, result); + + if (count != 1) { + DEBUG(1, ("Unexpected number of results [%d] for realm " + "search.\n", count)); + ldap_msgfree(result); + talloc_free(dn); + return NT_STATUS_UNSUCCESSFUL; + } + + entry = ldap_first_entry(smbldap_state->ldap_struct, result); + if (entry == NULL) { + DEBUG(0, ("Could not get krbrealmcontainer entry\n")); + ldap_msgfree(result); + talloc_free(dn); + return NT_STATUS_UNSUCCESSFUL; + } + + enctype_list = get_attribute_values(dn, smbldap_state->ldap_struct, entry, + "krbDefaultEncSaltTypes", &count); + ldap_msgfree(result); + if (enctype_list == NULL) { + talloc_free(dn); + return NT_STATUS_UNSUCCESSFUL; + } + + *enctypes = 0; + for (i = 0; i < count ; i++) { + char *enc = strchr(enctype_list[i], ':'); + if (enc != NULL) { + *enc = '\0'; + } + err = krb5_string_to_enctype(enctype_list[i], &enctype); + if (enc != NULL) { + *enc = ':'; + } + if (err) { + continue; + } + switch (enctype) { + case ENCTYPE_DES_CBC_CRC: + *enctypes |= KERB_ENCTYPE_DES_CBC_CRC; + break; + case ENCTYPE_DES_CBC_MD5: + *enctypes |= KERB_ENCTYPE_DES_CBC_MD5; + break; + case ENCTYPE_ARCFOUR_HMAC: + *enctypes |= KERB_ENCTYPE_RC4_HMAC_MD5; + break; + case ENCTYPE_AES128_CTS_HMAC_SHA1_96: + *enctypes |= KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96; + break; + case ENCTYPE_AES256_CTS_HMAC_SHA1_96: + *enctypes |= KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96; + break; + default: + break; + } + } + + talloc_free(dn); + return NT_STATUS_OK; +} + static NTSTATUS ipasam_get_realm(struct ldapsam_privates *ldap_state, TALLOC_CTX *mem_ctx, char **realm) @@ -4135,7 +4227,6 @@ done: return status; } - static NTSTATUS pdb_init_ipasam(struct pdb_methods **pdb_method, const char *location) { @@ -4151,6 +4242,7 @@ static NTSTATUS pdb_init_ipasam(struct pdb_methods **pdb_method, LDAPMessage *result = NULL; LDAPMessage *entry = NULL; enum idmap_error_code err; + uint32_t enctypes = 0; status = make_pdb_method(pdb_method); if (!NT_STATUS_IS_OK(status)) { @@ -4328,6 +4420,19 @@ static NTSTATUS pdb_init_ipasam(struct pdb_methods **pdb_method, } ldap_msgfree(result); + + status = ipasam_get_enctypes(ldap_state, + ldap_state->ipasam_privates, + &enctypes); + + if (!NT_STATUS_IS_OK(status)) { + enctypes = KERB_ENCTYPE_RC4_HMAC_MD5 | + KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96 | + KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96; + } + + ldap_state->ipasam_privates->supported_enctypes = enctypes; + (*pdb_method)->getsampwnam = ldapsam_getsampwnam; (*pdb_method)->search_users = ldapsam_search_users; (*pdb_method)->search_groups = ldapsam_search_groups; -- cgit