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.
This commit is contained in:
Alexander Bokovoy
2013-09-05 08:13:53 +03:00
committed by Petr Viktorin
parent 316a9c2159
commit 9cf8ec79c9
3 changed files with 81 additions and 41 deletions

View File

@@ -2229,11 +2229,14 @@ static NTSTATUS ipasam_set_trusted_domain(struct pdb_methods *methods,
LDAPMod **mods; LDAPMod **mods;
bool res; bool res;
char *trusted_dn = NULL; char *trusted_dn = NULL;
int ret, i; int ret, i, count;
NTSTATUS status; NTSTATUS status;
TALLOC_CTX *tmp_ctx; TALLOC_CTX *tmp_ctx;
char *trustpw; char *trustpw;
char *sid; 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)); 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; mods = NULL;
if (entry == NULL) {
smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "objectClass", smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "objectClass",
LDAP_OBJ_TRUSTED_DOMAIN); LDAP_OBJ_TRUSTED_DOMAIN);
smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "objectClass", smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "objectClass",
LDAP_OBJ_ID_OBJECT); LDAP_OBJ_ID_OBJECT);
}
if (entry != NULL) { if (entry != NULL) {
sid = get_single_attribute(tmp_ctx, priv2ld(ldap_state), entry, sid = get_single_attribute(tmp_ctx, priv2ld(ldap_state), entry,
@@ -2314,27 +2319,38 @@ static NTSTATUS ipasam_set_trusted_domain(struct pdb_methods *methods,
} }
} }
trust_offset = 0;
if (td->trust_posix_offset != NULL) { if (td->trust_posix_offset != NULL) {
trust_offset = *td->trust_posix_offset;
}
res = smbldap_make_mod_uint32_t(priv2ld(ldap_state), entry, res = smbldap_make_mod_uint32_t(priv2ld(ldap_state), entry,
&mods, &mods,
LDAP_ATTRIBUTE_TRUST_POSIX_OFFSET, LDAP_ATTRIBUTE_TRUST_POSIX_OFFSET,
*td->trust_posix_offset); trust_offset);
if (!res) { if (!res) {
status = NT_STATUS_UNSUCCESSFUL; status = NT_STATUS_UNSUCCESSFUL;
goto done; 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) { if (td->supported_enc_type != NULL) {
enctypes = *td->supported_enc_type;
}
res = smbldap_make_mod_uint32_t(priv2ld(ldap_state), entry, res = smbldap_make_mod_uint32_t(priv2ld(ldap_state), entry,
&mods, &mods,
LDAP_ATTRIBUTE_SUPPORTED_ENC_TYPE, LDAP_ATTRIBUTE_SUPPORTED_ENC_TYPE,
*td->supported_enc_type); enctypes);
if (!res) { if (!res) {
status = NT_STATUS_UNSUCCESSFUL; status = NT_STATUS_UNSUCCESSFUL;
goto done; goto done;
} }
}
if (td->trust_auth_outgoing.data != NULL) { if (td->trust_auth_outgoing.data != NULL) {
smbldap_make_mod_blob(priv2ld(ldap_state), entry, &mods, smbldap_make_mod_blob(priv2ld(ldap_state), entry, &mods,
@@ -2354,22 +2370,35 @@ static NTSTATUS ipasam_set_trusted_domain(struct pdb_methods *methods,
&td->trust_forest_trust_info); &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++) { for (i = 0; ipa_mspac_well_known_sids[i]; i++) {
if (in_blacklist == NULL) {
smbldap_make_mod(priv2ld(ldap_state), entry, &mods, smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
LDAP_ATTRIBUTE_SID_BLACKLIST_INCOMING, LDAP_ATTRIBUTE_SID_BLACKLIST_INCOMING,
ipa_mspac_well_known_sids[i]); ipa_mspac_well_known_sids[i]);
}
if (out_blacklist == NULL) {
smbldap_make_mod(priv2ld(ldap_state), entry, &mods, smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
LDAP_ATTRIBUTE_SID_BLACKLIST_OUTGOING, LDAP_ATTRIBUTE_SID_BLACKLIST_OUTGOING,
ipa_mspac_well_known_sids[i]); ipa_mspac_well_known_sids[i]);
} }
}
smbldap_talloc_autofree_ldapmod(tmp_ctx, mods); smbldap_talloc_autofree_ldapmod(tmp_ctx, mods);
if (mods != NULL) {
trusted_dn = trusted_domain_dn(tmp_ctx, ldap_state, domain); trusted_dn = trusted_domain_dn(tmp_ctx, ldap_state, domain);
if (trusted_dn == NULL) { if (trusted_dn == NULL) {
status = NT_STATUS_NO_MEMORY; status = NT_STATUS_NO_MEMORY;
goto done; goto done;
} }
if (entry == NULL) { if (entry == NULL) {
ret = smbldap_add(ldap_state->smbldap_state, trusted_dn, mods); ret = smbldap_add(ldap_state->smbldap_state, trusted_dn, mods);
} else { } else {
@@ -2380,6 +2409,7 @@ static NTSTATUS ipasam_set_trusted_domain(struct pdb_methods *methods,
status = NT_STATUS_UNSUCCESSFUL; status = NT_STATUS_UNSUCCESSFUL;
goto done; goto done;
} }
}
if (entry == NULL) { /* FIXME: allow password updates here */ if (entry == NULL) { /* FIXME: allow password updates here */
status = get_trust_pwd(tmp_ctx, &td->trust_auth_incoming, status = get_trust_pwd(tmp_ctx, &td->trust_auth_incoming,

View File

@@ -54,6 +54,7 @@ default: cn: trusts
# 2. cn=trust admins,cn=groups,cn=accounts,$SUFFIX can manage trusts (via ipa tools) # 2. cn=trust admins,cn=groups,cn=accounts,$SUFFIX can manage trusts (via ipa tools)
dn: cn=trusts,$SUFFIX 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";)' 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";)' 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";)' 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";)'

View File

@@ -912,12 +912,21 @@ class TrustDomainInstance(object):
raise assess_dcerpc_exception(num=num, message=message) raise assess_dcerpc_exception(num=num, message=message)
try: 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 = lsa.TrustDomainInfoSupportedEncTypes()
infoclass.enc_types = security.KERB_ENCTYPE_RC4_HMAC_MD5 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_AES128_CTS_HMAC_SHA1_96
infoclass.enc_types |= security.KERB_ENCTYPE_AES256_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) self._pipe.SetInformationTrustedDomain(trustdom_handle, lsa.LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES, infoclass)
except RuntimeError, e: 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 pass
def verify_trust(self, another_domain): def verify_trust(self, another_domain):