[Freeipa-devel] [PATCH] 0114 ipa-sam: fix setting encryption type for trust object already created

Alexander Bokovoy abokovoy at redhat.com
Tue Sep 10 16:31:37 UTC 2013


On Sat, 07 Sep 2013, Simo Sorce wrote:
>On Sat, 2013-09-07 at 21:32 +0300, Alexander Bokovoy wrote:
>> On Sat, 07 Sep 2013, Simo Sorce wrote:
>> >On Sat, 2013-09-07 at 21:01 +0300, Alexander Bokovoy wrote:
>> >> On Sat, 07 Sep 2013, Simo Sorce wrote:
>> >> >On Thu, 2013-09-05 at 17:44 +0300, Alexander Bokovoy wrote:
>> >> >> +       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;
>> >> >
>> >> >Why are we hardcoding support for *DES* enctype, we disable DES by
>> >> >default and also Windows never uses it by default.
>> >> This is actually a copy of the same statement from
>> >> fill_pdb_trusted_domain().
>> >>
>> >> Should I remove it?
>> >
>> >Yes please remove DES types, is there any chance we can make this list
>> >configurable ? (not a hard requirement, only if ti is something easy to
>> >do, maybe as a further enhancement down the road).
>> If you can point me to some place in cn=config or $SUFFIX that could be
>> read by cifs/fqdn on ipa-sam module init, I can look in fetching that.
>> But I suspect it is much harder to deduce exact list of supported types.
>
>Look in:
>cn=REALM.NAME,cn=kerberos,$SUFFIX
>
>there we have 2 lists:
>krbDefaultEncSaltTypes  <- use this
>krbSupportedEncSaltTypes
>
>in util/ipa_krb5.c we have then the funciton parse_bval_key_sal_tuples()
>that can covert strings to enctypes.
>
>> >> RC4 enctype will be the only one available for
>> >> Windows 2003 trusts then...
>> >
>> >It's the only one 2003 enables by default anyway and the only one that
>> >we can use as DES is disabled on FreeIPA.
>> Since admin could enable DES on FreeIPA manually, right now ipa-sam
>> would allow using DES to Windows 2003. If we remove DES enctypes
>> unconditionally, it would not be possible.
>
>If you look at the attributes I pointed you at above, then you have a
>way to support DES by simply changing the defaults and restarting
>FreeIPA.
>
>DES is dead anyway and not sufficiently secure for cross-realm keys
>anymore, even if we do not support it at all I think we are just fine.
Ok, attached three patches 0114-0116 is a new revision that implements also
fetching encryption types from the Kerberos configuration container.

The patches depend on each other in that order.

-- 
/ Alexander Bokovoy
-------------- next part --------------
From 875c3f5dff578962352fe3673b3a6bcf82014976 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy at redhat.com>
Date: Thu, 5 Sep 2013 08:13:53 +0300
Subject: [PATCH 1/3] ipa-sam: do not modify objectclass when trust object
 already created

When trust is established, last step done by IPA framework is to set
encryption types associated with the trust. This operation fails due
to ipa-sam attempting to modify object classes in trust object entry
which is not allowed by ACI.

Additionally, wrong handle was used by dcerpc.py code when executing
SetInformationTrustedDomain() against IPA smbd which prevented even to
reach the point where ipa-sam would be asked to modify the trust object.
---
 daemons/ipa-sam/ipa_sam.c        | 112 +++++++++++++++++++++++++--------------
 install/updates/60-trusts.update |   1 +
 ipaserver/dcerpc.py              |   9 ++++
 3 files changed, 81 insertions(+), 41 deletions(-)

diff --git a/daemons/ipa-sam/ipa_sam.c b/daemons/ipa-sam/ipa_sam.c
index 4a2fca5..cf39bb9 100644
--- a/daemons/ipa-sam/ipa_sam.c
+++ b/daemons/ipa-sam/ipa_sam.c
@@ -2229,11 +2229,14 @@ static NTSTATUS ipasam_set_trusted_domain(struct pdb_methods *methods,
 	LDAPMod **mods;
 	bool res;
 	char *trusted_dn = NULL;
-	int ret, i;
+	int ret, i, count;
 	NTSTATUS status;
 	TALLOC_CTX *tmp_ctx;
 	char *trustpw;
 	char *sid;
+	char **in_blacklist = NULL;
+	char **out_blacklist = NULL;
+	uint32_t enctypes, trust_offset;
 
 	DEBUG(10, ("ipasam_set_trusted_domain called for domain %s\n", domain));
 
@@ -2250,10 +2253,12 @@ static NTSTATUS ipasam_set_trusted_domain(struct pdb_methods *methods,
 	}
 
 	mods = NULL;
-	smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "objectClass",
-			 LDAP_OBJ_TRUSTED_DOMAIN);
-	smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "objectClass",
-			 LDAP_OBJ_ID_OBJECT);
+	if (entry == NULL) {
+		smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "objectClass",
+				 LDAP_OBJ_TRUSTED_DOMAIN);
+		smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "objectClass",
+				 LDAP_OBJ_ID_OBJECT);
+	}
 
 	if (entry != NULL) {
 		sid = get_single_attribute(tmp_ctx, priv2ld(ldap_state), entry,
@@ -2314,26 +2319,37 @@ static NTSTATUS ipasam_set_trusted_domain(struct pdb_methods *methods,
 		}
 	}
 
+	trust_offset = 0;
 	if (td->trust_posix_offset != NULL) {
-		res = smbldap_make_mod_uint32_t(priv2ld(ldap_state), entry,
-						&mods,
-						LDAP_ATTRIBUTE_TRUST_POSIX_OFFSET,
-						*td->trust_posix_offset);
-		if (!res) {
-			status = NT_STATUS_UNSUCCESSFUL;
-			goto done;
-		}
+		trust_offset = *td->trust_posix_offset;
 	}
 
+	res = smbldap_make_mod_uint32_t(priv2ld(ldap_state), entry,
+					&mods,
+					LDAP_ATTRIBUTE_TRUST_POSIX_OFFSET,
+					trust_offset);
+	if (!res) {
+		status = NT_STATUS_UNSUCCESSFUL;
+		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;
+
 	if (td->supported_enc_type != NULL) {
-		res = smbldap_make_mod_uint32_t(priv2ld(ldap_state), entry,
-						&mods,
-						LDAP_ATTRIBUTE_SUPPORTED_ENC_TYPE,
-						*td->supported_enc_type);
-		if (!res) {
-			status = NT_STATUS_UNSUCCESSFUL;
-			goto done;
-		}
+		enctypes = *td->supported_enc_type;
+	}
+
+	res = smbldap_make_mod_uint32_t(priv2ld(ldap_state), entry,
+					&mods,
+					LDAP_ATTRIBUTE_SUPPORTED_ENC_TYPE,
+					enctypes);
+	if (!res) {
+		status = NT_STATUS_UNSUCCESSFUL;
+		goto done;
 	}
 
 	if (td->trust_auth_outgoing.data != NULL) {
@@ -2354,31 +2370,45 @@ static NTSTATUS ipasam_set_trusted_domain(struct pdb_methods *methods,
 				      &td->trust_forest_trust_info);
 	}
 
+
+	/* Only add default blacklists for incoming and outgoing SIDs but don't modify existing ones */
+	in_blacklist = get_attribute_values(tmp_ctx, ldap_state->smbldap_state->ldap_struct, entry,
+						LDAP_ATTRIBUTE_SID_BLACKLIST_INCOMING, &count);
+	out_blacklist = get_attribute_values(tmp_ctx, ldap_state->smbldap_state->ldap_struct, entry,
+						LDAP_ATTRIBUTE_SID_BLACKLIST_OUTGOING, &count);
+
 	for (i = 0; ipa_mspac_well_known_sids[i]; i++) {
-		smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
-				      LDAP_ATTRIBUTE_SID_BLACKLIST_INCOMING,
-				      ipa_mspac_well_known_sids[i]);
-		smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
-				      LDAP_ATTRIBUTE_SID_BLACKLIST_OUTGOING,
-				      ipa_mspac_well_known_sids[i]);
+		if (in_blacklist == NULL) {
+			smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
+					      LDAP_ATTRIBUTE_SID_BLACKLIST_INCOMING,
+					      ipa_mspac_well_known_sids[i]);
+		}
+		if (out_blacklist == NULL) {
+			smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
+					      LDAP_ATTRIBUTE_SID_BLACKLIST_OUTGOING,
+					      ipa_mspac_well_known_sids[i]);
+		}
 	}
 
 	smbldap_talloc_autofree_ldapmod(tmp_ctx, mods);
 
-	trusted_dn = trusted_domain_dn(tmp_ctx, ldap_state, domain);
-	if (trusted_dn == NULL) {
-		status = NT_STATUS_NO_MEMORY;
-		goto done;
-	}
-	if (entry == NULL) {
-		ret = smbldap_add(ldap_state->smbldap_state, trusted_dn, mods);
-	} else {
-		ret = smbldap_modify(ldap_state->smbldap_state, trusted_dn, mods);
-	}
-	if (ret != LDAP_SUCCESS) {
-		DEBUG(1, ("error writing trusted domain data!\n"));
-		status = NT_STATUS_UNSUCCESSFUL;
-		goto done;
+	if (mods != NULL) {
+		trusted_dn = trusted_domain_dn(tmp_ctx, ldap_state, domain);
+		if (trusted_dn == NULL) {
+			status = NT_STATUS_NO_MEMORY;
+			goto done;
+		}
+
+		if (entry == NULL) {
+			ret = smbldap_add(ldap_state->smbldap_state, trusted_dn, mods);
+		} else {
+			ret = smbldap_modify(ldap_state->smbldap_state, trusted_dn, mods);
+		}
+		if (ret != LDAP_SUCCESS) {
+			DEBUG(1, ("error writing trusted domain data!\n"));
+			status = NT_STATUS_UNSUCCESSFUL;
+			goto done;
+		}
 	}
 
 	if (entry == NULL) { /* FIXME: allow password updates here */
diff --git a/install/updates/60-trusts.update b/install/updates/60-trusts.update
index 1b25115..46de01a 100644
--- a/install/updates/60-trusts.update
+++ b/install/updates/60-trusts.update
@@ -54,6 +54,7 @@ default: cn: trusts
 # 2. cn=trust admins,cn=groups,cn=accounts,$SUFFIX can manage trusts (via ipa tools)
 dn: cn=trusts,$SUFFIX
 add:aci: '(target = "ldap:///cn=trusts,$SUFFIX")(targetattr = "ipaNTTrustType || ipaNTTrustAttributes || ipaNTTrustDirection || ipaNTTrustPartner || ipaNTFlatName || ipaNTTrustAuthOutgoing || ipaNTTrustAuthIncoming || ipaNTSecurityIdentifier || ipaNTTrustForestTrustInfo || ipaNTTrustPosixOffset || ipaNTSupportedEncryptionTypes || krbPrincipalName || krbLastPwdChange || krbTicketFlags || krbLoginFailedCount || krbExtraData || krbPrincipalKey")(version 3.0;acl "Allow trust system user to create and delete trust accounts and cross realm principals"; allow (read,write,add,delete) groupdn="ldap:///cn=adtrust agents,cn=sysaccounts,cn=etc,$SUFFIX";)'
+replace:aci:'(target = "ldap:///cn=trusts,$SUFFIX")(targetattr = "ipaNTTrustType || ipaNTTrustAttributes || ipaNTTrustDirection || ipaNTTrustPartner || ipaNTFlatName || ipaNTTrustAuthOutgoing || ipaNTTrustAuthIncoming || ipaNTSecurityIdentifier || ipaNTTrustForestTrustInfo || ipaNTTrustPosixOffset || ipaNTSupportedEncryptionTypes || krbPrincipalName || krbLastPwdChange || krbTicketFlags || krbLoginFailedCount || krbExtraData || krbPrincipalKey")(version 3.0;acl "Allow trust system user to create and delete trust accounts and cross realm principals"; allow (read,write,add,delete) groupdn="ldap:///cn=adtrust agents,cn=sysaccounts,cn=etc,$SUFFIX";)::(target = "ldap:///cn=trusts,$SUFFIX")(targetattr = "ipaNTTrustType || ipaNTTrustAttributes || ipaNTTrustDirection || ipaNTTrustPartner || ipaNTFlatName || ipaNTTrustAuthOutgoing || ipaNTTrustAuthIncoming || ipaNTSecurityIdentifier || ipaNTTrustForestTrustInfo || ipaNTTrustPosixOffset || ipaNTSupportedEncryptionTypes || ipaNTSIDBlacklistIncoming || ipaNTSIDBlacklistOutgoing || krbPrincipalName || krbLastPwdChange || krbTicketFlags || krbLoginFailedCount || krbExtraData || krbPrincipalKey")(version 3.0;acl "Allow trust system user to create and delete trust accounts and cross realm principals"; allow (read,write,add,delete) groupdn="ldap:///cn=adtrust agents,cn=sysaccounts,cn=etc,$SUFFIX";)'
 replace:aci:'(target = "ldap:///cn=trusts,$SUFFIX")(targetattr = "ipaNTTrustType || ipaNTTrustAttributes || ipaNTTrustDirection || ipaNTTrustPartner || ipaNTFlatName || ipaNTTrustAuthOutgoing || ipaNTTrustAuthIncoming || ipaNTSecurityIdentifier || ipaNTTrustForestTrustInfo || ipaNTTrustPosixOffset || ipaNTSupportedEncryptionTypes")(version 3.0;acl "Allow trust admins manage trust accounts"; allow (read,write,add,delete) groupdn="ldap:///cn=trust admins,cn=groups,cn=accounts,$SUFFIX";)::(target = "ldap:///cn=trusts,$SUFFIX")(targetattr = "ipaNTTrustType || ipaNTTrustAttributes || ipaNTTrustDirection || ipaNTTrustPartner || ipaNTFlatName || ipaNTTrustAuthOutgoing || ipaNTTrustAuthIncoming || ipaNTSecurityIdentifier || ipaNTTrustForestTrustInfo || ipaNTTrustPosixOffset || ipaNTSupportedEncryptionTypes || ipaNTSIDBlacklistIncoming || ipaNTSIDBlacklistOutgoing")(version 3.0;acl "Allow trust admins manage trust accounts"; allow (read,write,add,delete) groupdn="ldap:///cn=trust admins,cn=groups,cn=accounts,$SUFFIX";)'
 add:aci: '(target = "ldap:///cn=trusts,$SUFFIX")(targetattr = "ipaNTTrustType || ipaNTTrustAttributes || ipaNTTrustDirection || ipaNTTrustPartner || ipaNTFlatName || ipaNTTrustAuthOutgoing || ipaNTTrustAuthIncoming || ipaNTSecurityIdentifier || ipaNTTrustForestTrustInfo || ipaNTTrustPosixOffset || ipaNTSupportedEncryptionTypes || ipaNTSIDBlacklistIncoming || ipaNTSIDBlacklistOutgoing")(version 3.0;acl "Allow trust admins manage trust accounts"; allow (read,write,add,delete) groupdn="ldap:///cn=trust admins,cn=groups,cn=accounts,$SUFFIX";)'
 
diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
index a27a64d..bd8f5aa 100644
--- a/ipaserver/dcerpc.py
+++ b/ipaserver/dcerpc.py
@@ -912,12 +912,21 @@ class TrustDomainInstance(object):
             raise assess_dcerpc_exception(num=num, message=message)
 
         try:
+            # We should use proper trustdom handle in order to modify the
+            # trust settings. Samba insists this has to be done with LSA
+            # OpenTrustedDomain* calls, it is not enough to have a handle
+            # returned by the CreateTrustedDomainEx2 call.
+            trustdom_handle = self._pipe.OpenTrustedDomainByName(self._policy_handle, dname, security.SEC_FLAG_MAXIMUM_ALLOWED)
             infoclass = lsa.TrustDomainInfoSupportedEncTypes()
             infoclass.enc_types = security.KERB_ENCTYPE_RC4_HMAC_MD5
             infoclass.enc_types |= security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96
             infoclass.enc_types |= security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96
             self._pipe.SetInformationTrustedDomain(trustdom_handle, lsa.LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES, infoclass)
         except RuntimeError, e:
+            # We can ignore the error here -- changing enctypes is for
+            # improved security but the trust will work with default values as
+            # well. In particular, the call may fail against Windows 2003
+            # server as that one doesn't support AES encryption types
             pass
 
     def verify_trust(self, another_domain):
-- 
1.8.3.1

-------------- next part --------------
>From 4bd9901d0e3336dcd7e19e2b426ad0140ca3efb5 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy at redhat.com>
Date: Mon, 9 Sep 2013 15:52:17 +0300
Subject: [PATCH 2/3] ipa-sam: do not leak LDAPMessage on ipa-sam
 initialization

We used to handle some of code paths to free memory allocated by the LDAP library
but there are few more unhandled. In addition, search result wasn't freed on successful
initialization, leaking for long time.

https://fedorahosted.org/freeipa/ticket/3913
---
 daemons/ipa-sam/ipa_sam.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/daemons/ipa-sam/ipa_sam.c b/daemons/ipa-sam/ipa_sam.c
index cf39bb9..b4d1a32 100644
--- a/daemons/ipa-sam/ipa_sam.c
+++ b/daemons/ipa-sam/ipa_sam.c
@@ -4273,6 +4273,7 @@ static NTSTATUS pdb_init_ipasam(struct pdb_methods **pdb_method,
 	if (ldap_state->ipasam_privates->flat_name == NULL) {
 		DEBUG(0, ("Missing mandatory attribute %s.\n",
 			  LDAP_ATTRIBUTE_FLAT_NAME));
+		ldap_msgfree(result);
 		return NT_STATUS_INVALID_PARAMETER;
 	}
 
@@ -4280,8 +4281,9 @@ static NTSTATUS pdb_init_ipasam(struct pdb_methods **pdb_method,
 			     idmap_talloc_free,
 			     &ldap_state->ipasam_privates->idmap_ctx);
 	if (err != IDMAP_SUCCESS) {
-	    DEBUG(1, ("Failed to setup idmap context.\n"));
-	    return NT_STATUS_UNSUCCESSFUL;
+		DEBUG(1, ("Failed to setup idmap context.\n"));
+		ldap_msgfree(result);
+		return NT_STATUS_UNSUCCESSFUL;
 	}
 
 	fallback_group_sid = get_fallback_group_sid(ldap_state,
@@ -4290,6 +4292,7 @@ static NTSTATUS pdb_init_ipasam(struct pdb_methods **pdb_method,
 					result);
 	if (fallback_group_sid == NULL) {
 		DEBUG(0, ("Cannot find SID of fallback group.\n"));
+		ldap_msgfree(result);
 		return NT_STATUS_INVALID_PARAMETER;
 	}
 	sid_copy(&ldap_state->ipasam_privates->fallback_primary_group,
@@ -4319,10 +4322,12 @@ static NTSTATUS pdb_init_ipasam(struct pdb_methods **pdb_method,
 
 		status = save_sid_to_secret(ldap_state);
 		if (!NT_STATUS_IS_OK(status)) {
+			ldap_msgfree(result);
 			return status;
 		}
 	}
 
+	ldap_msgfree(result);
 	(*pdb_method)->getsampwnam = ldapsam_getsampwnam;
 	(*pdb_method)->search_users = ldapsam_search_users;
 	(*pdb_method)->search_groups = ldapsam_search_groups;
-- 
1.8.3.1

-------------- next part --------------
>From 450ea23bc89b9614a50a093f876903c3a6a92701 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy at redhat.com>
Date: Tue, 10 Sep 2013 11:56:40 +0300
Subject: [PATCH 3/3] 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(-)

diff --git a/daemons/ipa-sam/ipa_sam.c b/daemons/ipa-sam/ipa_sam.c
index b4d1a32..a535c0f 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;
-- 
1.8.3.1



More information about the Freeipa-devel mailing list