mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
adtrust: support UPNs for trusted domain users
Add support for additional user name principal suffixes from trusted Active Directory forests. UPN suffixes are property of the forest and as such are associated with the forest root domain. FreeIPA stores UPN suffixes as ipaNTAdditionalSuffixes multi-valued attribute of ipaNTTrustedDomain object class. In order to look up UPN suffixes, netr_DsRGetForestTrustInformation LSA RPC call is used instead of netr_DsrEnumerateDomainTrusts. For more details on UPN and naming in Active Directory see https://technet.microsoft.com/en-us/library/cc739093%28v=ws.10%29.aspx https://fedorahosted.org/freeipa/ticket/5354 Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
This commit is contained in:
committed by
Martin Basti
parent
b506fd178e
commit
bb75f5a583
2
ACI.txt
2
ACI.txt
@@ -309,7 +309,7 @@ aci: (targetattr = "cmdcategory || cn || createtimestamp || description || entry
|
||||
dn: dc=ipa,dc=example
|
||||
aci: (targetattr = "cn || createtimestamp || description || entryusn || modifytimestamp || objectclass || ou || sudocommand || sudohost || sudonotafter || sudonotbefore || sudooption || sudoorder || sudorunas || sudorunasgroup || sudorunasuser || sudouser")(target = "ldap:///ou=sudoers,dc=ipa,dc=example")(version 3.0;acl "permission:System: Read Sudoers compat tree";allow (compare,read,search) userdn = "ldap:///anyone";)
|
||||
dn: cn=trusts,dc=ipa,dc=example
|
||||
aci: (targetattr = "cn || createtimestamp || entryusn || ipantflatname || ipantsecurityidentifier || ipantsidblacklistincoming || ipantsidblacklistoutgoing || ipanttrustdirection || ipanttrusteddomainsid || ipanttrustpartner || modifytimestamp || objectclass")(version 3.0;acl "permission:System: Read Trust Information";allow (compare,read,search) userdn = "ldap:///all";)
|
||||
aci: (targetattr = "cn || createtimestamp || entryusn || ipantadditionalsuffixes || ipantflatname || ipantsecurityidentifier || ipantsidblacklistincoming || ipantsidblacklistoutgoing || ipanttrustdirection || ipanttrusteddomainsid || ipanttrustpartner || modifytimestamp || objectclass")(version 3.0;acl "permission:System: Read Trust Information";allow (compare,read,search) userdn = "ldap:///all";)
|
||||
dn: cn=trusts,dc=ipa,dc=example
|
||||
aci: (targetattr = "gidnumber || krbprincipalname || uidnumber")(version 3.0;acl "permission:System: Read system trust accounts";allow (compare,read,search) groupdn = "ldap:///cn=System: Read system trust accounts,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||
dn: cn=groups,cn=accounts,dc=ipa,dc=example
|
||||
|
||||
@@ -2273,7 +2273,7 @@ static char *get_server_netbios_name(struct ipadb_context *ipactx)
|
||||
|
||||
void ipadb_mspac_struct_free(struct ipadb_mspac **mspac)
|
||||
{
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
if (!*mspac) return;
|
||||
|
||||
@@ -2290,6 +2290,12 @@ void ipadb_mspac_struct_free(struct ipadb_mspac **mspac)
|
||||
free((*mspac)->trusts[i].sid_blacklist_outgoing);
|
||||
free((*mspac)->trusts[i].parent_name);
|
||||
(*mspac)->trusts[i].parent = NULL;
|
||||
if ((*mspac)->trusts[i].upn_suffixes) {
|
||||
for (j = 0; (*mspac)->trusts[i].upn_suffixes[j]; j++) {
|
||||
free((*mspac)->trusts[i].upn_suffixes[j]);
|
||||
}
|
||||
free((*mspac)->trusts[i].upn_suffixes);
|
||||
}
|
||||
}
|
||||
free((*mspac)->trusts);
|
||||
}
|
||||
@@ -2405,7 +2411,7 @@ krb5_error_code ipadb_mspac_get_trusted_domains(struct ipadb_context *ipactx)
|
||||
LDAP *lc = ipactx->lcontext;
|
||||
char *attrs[] = { "cn", "ipaNTTrustPartner", "ipaNTFlatName",
|
||||
"ipaNTTrustedDomainSID", "ipaNTSIDBlacklistIncoming",
|
||||
"ipaNTSIDBlacklistOutgoing", NULL };
|
||||
"ipaNTSIDBlacklistOutgoing", "ipaNTAdditionalSuffixes", NULL };
|
||||
char *filter = "(objectclass=ipaNTTrustedDomain)";
|
||||
krb5_error_code kerr;
|
||||
LDAPMessage *res = NULL;
|
||||
@@ -2462,26 +2468,42 @@ krb5_error_code ipadb_mspac_get_trusted_domains(struct ipadb_context *ipactx)
|
||||
goto done;
|
||||
}
|
||||
|
||||
t[n].flat_name = NULL;
|
||||
ret = ipadb_ldap_attr_to_str(lc, le, "ipaNTFlatName",
|
||||
&t[n].flat_name);
|
||||
if (ret) {
|
||||
if (ret && ret != ENOENT) {
|
||||
ret = EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
t[n].domain_sid = NULL;
|
||||
ret = ipadb_ldap_attr_to_str(lc, le, "ipaNTTrustedDomainSID",
|
||||
&t[n].domain_sid);
|
||||
if (ret) {
|
||||
if (ret && ret != ENOENT) {
|
||||
ret = EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = string_to_sid(t[n].domain_sid, &t[n].domsid);
|
||||
if (ret) {
|
||||
if (ret && t[n].domain_sid != NULL) {
|
||||
ret = EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = ipadb_ldap_attr_to_strlist(lc, le, "ipaNTAdditionalSuffixes",
|
||||
&t[n].upn_suffixes);
|
||||
|
||||
if (ret) {
|
||||
if (ret == ENOENT) {
|
||||
/* This attribute is optional */
|
||||
ret = 0;
|
||||
t[n].upn_suffixes = NULL;
|
||||
} else {
|
||||
ret = EINVAL;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ipadb_ldap_attr_to_strlist(lc, le, "ipaNTSIDBlacklistIncoming",
|
||||
&sid_blacklist_incoming);
|
||||
|
||||
@@ -2808,6 +2830,7 @@ krb5_error_code ipadb_is_princ_from_trusted_realm(krb5_context kcontext,
|
||||
struct ipadb_context *ipactx;
|
||||
int i, j, length;
|
||||
const char *name;
|
||||
bool result = false;
|
||||
|
||||
if (test_realm == NULL || test_realm[0] == '\0') {
|
||||
return KRB5_KDB_NOENTRY;
|
||||
@@ -2829,12 +2852,27 @@ krb5_error_code ipadb_is_princ_from_trusted_realm(krb5_context kcontext,
|
||||
|
||||
/* Iterate through list of trusts and check if input realm belongs to any of the trust */
|
||||
for(i = 0 ; i < ipactx->mspac->num_trusts ; i++) {
|
||||
if ((strncasecmp(test_realm,
|
||||
ipactx->mspac->trusts[i].domain_name,
|
||||
size) == 0) ||
|
||||
(strncasecmp(test_realm,
|
||||
ipactx->mspac->trusts[i].flat_name,
|
||||
size) == 0)) {
|
||||
result = strncasecmp(test_realm,
|
||||
ipactx->mspac->trusts[i].domain_name,
|
||||
size) == 0;
|
||||
|
||||
if (!result && (ipactx->mspac->trusts[i].flat_name != NULL)) {
|
||||
result = strncasecmp(test_realm,
|
||||
ipactx->mspac->trusts[i].flat_name,
|
||||
size) == 0;
|
||||
}
|
||||
|
||||
if (!result && (ipactx->mspac->trusts[i].upn_suffixes != NULL)) {
|
||||
for (j = 0; ipactx->mspac->trusts[i].upn_suffixes[j]; j++) {
|
||||
result = strncasecmp(test_realm,
|
||||
ipactx->mspac->trusts[i].upn_suffixes[j],
|
||||
size) == 0;
|
||||
if (result)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result) {
|
||||
/* return the realm if caller supplied a place for it */
|
||||
if (trusted_realm != NULL) {
|
||||
name = (ipactx->mspac->trusts[i].parent_name != NULL) ?
|
||||
|
||||
@@ -47,6 +47,7 @@ struct ipadb_adtrusts {
|
||||
int len_sid_blacklist_outgoing;
|
||||
struct ipadb_adtrusts *parent;
|
||||
char *parent_name;
|
||||
char **upn_suffixes;
|
||||
};
|
||||
|
||||
int string_to_sid(const char *str, struct dom_sid *sid);
|
||||
|
||||
@@ -1023,8 +1023,13 @@ static int handle_name_request(struct ipa_extdom_ctx *ctx,
|
||||
char *buf = NULL;
|
||||
struct sss_nss_kv *kv_list = NULL;
|
||||
|
||||
ret = asprintf(&fq_name, "%s%c%s", name, SSSD_DOMAIN_SEPARATOR,
|
||||
domain_name);
|
||||
if (strchr(name, SSSD_DOMAIN_SEPARATOR) == NULL) {
|
||||
ret = asprintf(&fq_name, "%s%c%s", name, SSSD_DOMAIN_SEPARATOR,
|
||||
domain_name);
|
||||
} else {
|
||||
/* SSSD_DOMAIN_SEPARATOR already present, assume UPN */
|
||||
ret = asprintf(&fq_name, "%s", name);
|
||||
}
|
||||
if (ret == -1) {
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
set_err_msg(req, "Failed to create fully qualified name");
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
from ipaserver import dcerpc
|
||||
from ipaserver.install.installutils import is_ipa_configured, ScriptError
|
||||
from ipapython import config, ipautil
|
||||
from ipalib import api, errors
|
||||
from ipalib import api
|
||||
from ipapython.dn import DN
|
||||
from ipalib.config import Env
|
||||
from ipalib.constants import DEFAULT_CONFIG
|
||||
@@ -170,33 +170,8 @@ except gssapi.exceptions.GSSError:
|
||||
ipa_domain = api.env.domain
|
||||
os.environ['KRB5CCNAME'] = oneway_ccache_name
|
||||
domains = dcerpc.fetch_domains(api, ipa_domain, trusted_domain, creds=True)
|
||||
|
||||
if domains:
|
||||
# trust range must exist by the time fetch_domains_from_trust is called
|
||||
range_name = unicode(trusted_domain.upper() + '_id_range')
|
||||
old_range = api.Command.idrange_show(range_name, raw=True)['result']
|
||||
idrange_type = old_range['iparangetype'][0]
|
||||
|
||||
result = []
|
||||
for dom in domains:
|
||||
dom['trust_type'] = u'ad'
|
||||
try:
|
||||
name = dom['cn']
|
||||
del dom['cn']
|
||||
|
||||
res = api.Command.trustdomain_add(trusted_domain, name, **dom)
|
||||
result.append(res['result'])
|
||||
|
||||
if idrange_type != u'ipa-ad-trust-posix':
|
||||
range_name = name.upper() + '_id_range'
|
||||
dom['range_type'] = u'ipa-ad-trust'
|
||||
# Do not pass ipaserver.dcerpc.TrustInstance to trust.add_range
|
||||
# to force it using existing credentials cache
|
||||
trust.add_range(api, None, range_name, dom['ipanttrusteddomainsid'],
|
||||
trusted_domain, name, **dom)
|
||||
except errors.DuplicateEntry:
|
||||
# Ignore updating duplicate entries
|
||||
pass
|
||||
trust_domain_object = api.Command.trust_show(trusted_domain, raw=True)['result']
|
||||
trust.add_new_domains_from_trust(api, None, trust_domain_object, domains)
|
||||
|
||||
if old_ccache:
|
||||
os.environ['KRB5CCNAME'] = old_ccache
|
||||
|
||||
@@ -56,6 +56,7 @@ attributeTypes: (2.16.840.1.113730.3.8.11.64 NAME 'ipaSecretKeyRef' DESC 'DN of
|
||||
attributeTypes: (2.16.840.1.113730.3.8.11.65 NAME 'ipaWrappingMech' DESC 'PKCS#11 wrapping mechanism equivalent to CK_MECHANISM_TYPE' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'IPA v4.1')
|
||||
attributeTypes: (2.16.840.1.113730.3.8.11.70 NAME 'ipaPermTargetTo' DESC 'Destination location to move an entry IPA permission ACI' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'IPA v4.0' )
|
||||
attributeTypes: (2.16.840.1.113730.3.8.11.71 NAME 'ipaPermTargetFrom' DESC 'Source location from where moving an entry IPA permission ACI' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'IPA v4.0' )
|
||||
attributeTypes: ( 2.16.840.1.113730.3.8.11.75 NAME 'ipaNTAdditionalSuffixes' DESC 'Suffix for the user principal name associated with the domain' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
|
||||
attributeTypes: (2.16.840.1.113730.3.8.18.2.1 NAME 'ipaVaultType' DESC 'IPA vault type' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'IPA v4.2')
|
||||
attributeTypes: (2.16.840.1.113730.3.8.18.2.2 NAME 'ipaVaultSalt' DESC 'IPA vault salt' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'IPA v4.2' )
|
||||
# FIXME: https://bugzilla.redhat.com/show_bug.cgi?id=1267782
|
||||
@@ -64,7 +65,7 @@ objectClasses: (2.16.840.1.113730.3.8.12.1 NAME 'ipaExternalGroup' SUP top STRUC
|
||||
objectClasses: (2.16.840.1.113730.3.8.12.2 NAME 'ipaNTUserAttrs' SUP top AUXILIARY MUST ( ipaNTSecurityIdentifier ) MAY ( ipaNTHash $ ipaNTLogonScript $ ipaNTProfilePath $ ipaNTHomeDirectory $ ipaNTHomeDirectoryDrive ) X-ORIGIN 'IPA v3' )
|
||||
objectClasses: (2.16.840.1.113730.3.8.12.3 NAME 'ipaNTGroupAttrs' SUP top AUXILIARY MUST ( ipaNTSecurityIdentifier ) X-ORIGIN 'IPA v3' )
|
||||
objectClasses: (2.16.840.1.113730.3.8.12.4 NAME 'ipaNTDomainAttrs' SUP top AUXILIARY MUST ( ipaNTSecurityIdentifier $ ipaNTFlatName $ ipaNTDomainGUID ) MAY ( ipaNTFallbackPrimaryGroup ) X-ORIGIN 'IPA v3' )
|
||||
objectClasses: (2.16.840.1.113730.3.8.12.5 NAME 'ipaNTTrustedDomain' SUP top STRUCTURAL DESC 'Trusted Domain Object' MUST ( cn ) MAY ( ipaNTTrustType $ ipaNTTrustAttributes $ ipaNTTrustDirection $ ipaNTTrustPartner $ ipaNTFlatName $ ipaNTTrustAuthOutgoing $ ipaNTTrustAuthIncoming $ ipaNTTrustedDomainSID $ ipaNTTrustForestTrustInfo $ ipaNTTrustPosixOffset $ ipaNTSupportedEncryptionTypes $ ipaNTSIDBlacklistIncoming $ ipaNTSIDBlacklistOutgoing) )
|
||||
objectClasses: (2.16.840.1.113730.3.8.12.5 NAME 'ipaNTTrustedDomain' SUP top STRUCTURAL DESC 'Trusted Domain Object' MUST ( cn ) MAY ( ipaNTTrustType $ ipaNTTrustAttributes $ ipaNTTrustDirection $ ipaNTTrustPartner $ ipaNTFlatName $ ipaNTTrustAuthOutgoing $ ipaNTTrustAuthIncoming $ ipaNTTrustedDomainSID $ ipaNTTrustForestTrustInfo $ ipaNTTrustPosixOffset $ ipaNTSupportedEncryptionTypes $ ipaNTSIDBlacklistIncoming $ ipaNTSIDBlacklistOutgoing $ ipaNTAdditionalSuffixes) )
|
||||
objectClasses: (2.16.840.1.113730.3.8.12.6 NAME 'groupOfPrincipals' SUP top AUXILIARY MUST ( cn ) MAY ( memberPrincipal ) X-ORIGIN 'IPA v3' )
|
||||
objectClasses: (2.16.840.1.113730.3.8.12.7 NAME 'ipaKrb5DelegationACL' SUP groupOfPrincipals STRUCTURAL MAY ( ipaAllowToImpersonate $ ipaAllowedTarget ) X-ORIGIN 'IPA v3' )
|
||||
objectClasses: (2.16.840.1.113730.3.8.12.10 NAME 'ipaSELinuxUserMap' SUP ipaAssociation STRUCTURAL MUST ipaSELinuxUser MAY ( accessTime $ seeAlso ) X-ORIGIN 'IPA v3')
|
||||
|
||||
@@ -1197,7 +1197,10 @@ def fetch_domains(api, mydomain, trustdomain, creds=None, server=None):
|
||||
def communicate(td):
|
||||
td.init_lsa_pipe(td.info['dc'])
|
||||
netr_pipe = netlogon.netlogon(td.binding, td.parm, td.creds)
|
||||
domains = netr_pipe.netr_DsrEnumerateDomainTrusts(td.binding, 1)
|
||||
# Older FreeIPA versions used netr_DsrEnumerateDomainTrusts call
|
||||
# but it doesn't provide information about non-domain UPNs associated
|
||||
# with the forest, thus we have to use netr_DsRGetForestTrustInformation
|
||||
domains = netr_pipe.netr_DsRGetForestTrustInformation(td.info['dc'], '', 0)
|
||||
return domains
|
||||
|
||||
domains = None
|
||||
@@ -1225,6 +1228,7 @@ def fetch_domains(api, mydomain, trustdomain, creds=None, server=None):
|
||||
raise assess_dcerpc_exception(message=str(e))
|
||||
|
||||
td.info['dc'] = unicode(result.pdc_dns_name)
|
||||
td.info['name'] = unicode(result.dns_domain)
|
||||
if type(creds) is bool:
|
||||
# Rely on existing Kerberos credentials in the environment
|
||||
td.creds = credentials.Credentials()
|
||||
@@ -1254,16 +1258,30 @@ def fetch_domains(api, mydomain, trustdomain, creds=None, server=None):
|
||||
if domains is None:
|
||||
return None
|
||||
|
||||
result = []
|
||||
for t in domains.array:
|
||||
if (not (t.trust_flags & trust_flags['NETR_TRUST_FLAG_PRIMARY']) and
|
||||
(t.trust_flags & trust_flags['NETR_TRUST_FLAG_IN_FOREST'])):
|
||||
res = dict()
|
||||
res['cn'] = unicode(t.dns_name)
|
||||
res['ipantflatname'] = unicode(t.netbios_name)
|
||||
res['ipanttrusteddomainsid'] = unicode(t.sid)
|
||||
res['ipanttrustpartner'] = res['cn']
|
||||
result.append(res)
|
||||
result = {'domains': {}, 'suffixes': {}}
|
||||
# netr_DsRGetForestTrustInformation returns two types of entries:
|
||||
# domain information -- name, NetBIOS name, SID of the domain
|
||||
# top level name info -- a name suffix associated with the forest
|
||||
# We should ignore forest root name/name suffix as it is already part
|
||||
# of trust information for IPA purposes and only add what's inside the forest
|
||||
for t in domains.entries:
|
||||
if t.type == lsa.LSA_FOREST_TRUST_DOMAIN_INFO:
|
||||
tname = unicode(t.forest_trust_data.dns_domain_name.string)
|
||||
if tname == trustdomain:
|
||||
continue
|
||||
result['domains'][tname] = {
|
||||
'cn': tname,
|
||||
'ipantflatname': unicode(
|
||||
t.forest_trust_data.netbios_domain_name.string),
|
||||
'ipanttrusteddomainsid': unicode(
|
||||
t.forest_trust_data.domain_sid)
|
||||
}
|
||||
elif t.type == lsa.LSA_FOREST_TRUST_TOP_LEVEL_NAME:
|
||||
tname = unicode(t.forest_trust_data.string)
|
||||
if tname == trustdomain:
|
||||
continue
|
||||
|
||||
result['suffixes'][tname] = {'cn': tname}
|
||||
return result
|
||||
|
||||
|
||||
|
||||
@@ -487,11 +487,16 @@ class trust(LDAPObject):
|
||||
object_name_plural = _('trusts')
|
||||
object_class = ['ipaNTTrustedDomain']
|
||||
default_attributes = ['cn', 'ipantflatname', 'ipanttrusteddomainsid',
|
||||
'ipanttrusttype', 'ipanttrustattributes', 'ipanttrustdirection',
|
||||
'ipanttrustpartner', 'ipanttrustforesttrustinfo',
|
||||
'ipanttrustposixoffset', 'ipantsupportedencryptiontypes' ]
|
||||
'ipanttrusttype', 'ipanttrustattributes',
|
||||
'ipanttrustdirection', 'ipanttrustpartner',
|
||||
'ipanttrustforesttrustinfo',
|
||||
'ipanttrustposixoffset',
|
||||
'ipantsupportedencryptiontypes',
|
||||
'ipantadditionalsuffixes']
|
||||
search_display_attributes = ['cn', 'ipantflatname',
|
||||
'ipanttrusteddomainsid', 'ipanttrusttype']
|
||||
'ipanttrusteddomainsid', 'ipanttrusttype',
|
||||
'ipanttrustattributes',
|
||||
'ipantadditionalsuffixes']
|
||||
managed_permissions = {
|
||||
'System: Read Trust Information': {
|
||||
# Allow reading of attributes needed for SSSD subdomains support
|
||||
@@ -505,7 +510,7 @@ class trust(LDAPObject):
|
||||
'ipantflatname', 'ipantsecurityidentifier',
|
||||
'ipanttrusteddomainsid', 'ipanttrustpartner',
|
||||
'ipantsidblacklistincoming', 'ipantsidblacklistoutgoing',
|
||||
'ipanttrustdirection'
|
||||
'ipanttrustdirection', 'ipantadditionalsuffixes',
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1457,8 +1462,11 @@ class trustdomain(LDAPObject):
|
||||
object_name = _('trust domain')
|
||||
object_name_plural = _('trust domains')
|
||||
object_class = ['ipaNTTrustedDomain']
|
||||
default_attributes = ['cn', 'ipantflatname', 'ipanttrusteddomainsid', 'ipanttrustpartner']
|
||||
search_display_attributes = ['cn', 'ipantflatname', 'ipanttrusteddomainsid', ]
|
||||
default_attributes = ['cn', 'ipantflatname', 'ipanttrusteddomainsid',
|
||||
'ipanttrustpartner', 'ipantadditionalsuffixes']
|
||||
search_display_attributes = ['cn', 'ipantflatname',
|
||||
'ipanttrusteddomainsid',
|
||||
'ipantadditionalsuffixes']
|
||||
|
||||
label = _('Trusted domains')
|
||||
label_singular = _('Trusted domain')
|
||||
@@ -1496,9 +1504,10 @@ class trustdomain(LDAPObject):
|
||||
class trustdomain_find(LDAPSearch):
|
||||
__doc__ = _('Search domains of the trust')
|
||||
|
||||
has_output_params = LDAPSearch.has_output_params + (
|
||||
has_output_params = LDAPSearch.has_output_params + trust_output_params + (
|
||||
Flag('domain_enabled', label= _('Domain enabled')),
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, filters, attrs_list, base_dn, scope, *args, **options):
|
||||
return (filters, base_dn, ldap.SCOPE_SUBTREE)
|
||||
|
||||
@@ -1507,11 +1516,10 @@ class trustdomain_find(LDAPSearch):
|
||||
return truncated
|
||||
trust_dn = self.obj.get_dn(args[0], trust_type=u'ad')
|
||||
trust_entry = ldap.get_entry(trust_dn)
|
||||
blacklist = trust_entry.get('ipantsidblacklistincoming')
|
||||
for entry in entries:
|
||||
sid = entry['ipanttrusteddomainsid'][0]
|
||||
|
||||
blacklist = trust_entry.get('ipantsidblacklistincoming')
|
||||
if blacklist is None:
|
||||
sid = entry.get('ipanttrusteddomainsid', [None])[0]
|
||||
if sid is None:
|
||||
continue
|
||||
|
||||
if sid in blacklist:
|
||||
@@ -1536,10 +1544,12 @@ class trustdomain_add(LDAPCreate):
|
||||
|
||||
takes_options = LDAPCreate.takes_options + (_trust_type_option,)
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
if 'ipanttrustpartner' in options:
|
||||
entry_attrs['ipanttrustpartner'] = [options['ipanttrustpartner']]
|
||||
# ipaNTTrustPartner must always be set to the name of the trusted domain
|
||||
# See MS-ADTS 6.1.6.7.13
|
||||
entry_attrs['ipanttrustpartner'] = [dn[0]['cn']]
|
||||
return dn
|
||||
|
||||
|
||||
@register()
|
||||
class trustdomain_del(LDAPDelete):
|
||||
__doc__ = _('Remove infromation about the domain associated with the trust.')
|
||||
@@ -1582,9 +1592,11 @@ def fetch_domains_from_trust(myapi, trustinstance, trust_entry, **options):
|
||||
server = options.get('realm_server', None)
|
||||
domains = ipaserver.dcerpc.fetch_domains(myapi,
|
||||
trustinstance.local_flatname,
|
||||
trust_name, creds=creds, server=server)
|
||||
trust_name, creds=creds,
|
||||
server=server)
|
||||
return domains
|
||||
|
||||
|
||||
def add_new_domains_from_trust(myapi, trustinstance, trust_entry, domains, **options):
|
||||
result = []
|
||||
if not domains:
|
||||
@@ -1596,7 +1608,12 @@ def add_new_domains_from_trust(myapi, trustinstance, trust_entry, domains, **opt
|
||||
old_range = myapi.Command.idrange_show(range_name, raw=True)['result']
|
||||
idrange_type = old_range['iparangetype'][0]
|
||||
|
||||
for dom in domains:
|
||||
suffixes = list()
|
||||
suffixes.extend(y['cn']
|
||||
for x, y in six.iteritems(domains['suffixes'])
|
||||
if x not in domains['domains'])
|
||||
|
||||
for dom in six.itervalues(domains['domains']):
|
||||
dom['trust_type'] = u'ad'
|
||||
try:
|
||||
name = dom['cn']
|
||||
@@ -1612,13 +1629,27 @@ def add_new_domains_from_trust(myapi, trustinstance, trust_entry, domains, **opt
|
||||
if idrange_type != u'ipa-ad-trust-posix':
|
||||
range_name = name.upper() + '_id_range'
|
||||
dom['range_type'] = u'ipa-ad-trust'
|
||||
add_range(myapi, trustinstance, range_name, dom['ipanttrusteddomainsid'],
|
||||
add_range(myapi, trustinstance,
|
||||
range_name, dom['ipanttrusteddomainsid'],
|
||||
trust_name, name, **dom)
|
||||
except errors.DuplicateEntry:
|
||||
# Ignore updating duplicate entries
|
||||
pass
|
||||
|
||||
try:
|
||||
dn = myapi.Object.trust.get_dn(trust_name, trust_type=u'ad')
|
||||
ldap = myapi.Backend.ldap2
|
||||
entry = ldap.get_entry(dn)
|
||||
tlns = entry.get('ipantadditionalsuffixes', [])
|
||||
tlns.extend(x for x in suffixes if x not in tlns)
|
||||
entry['ipantadditionalsuffixes'] = tlns
|
||||
ldap.update_entry(entry)
|
||||
except errors.EmptyModlist:
|
||||
pass
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@register()
|
||||
class trust_fetch_domains(LDAPRetrieve):
|
||||
__doc__ = _('Refresh list of the domains associated with the trust')
|
||||
@@ -1694,7 +1725,7 @@ class trustdomain_enable(LDAPQuery):
|
||||
dn = self.obj.get_dn(keys[0], keys[1], trust_type=u'ad')
|
||||
try:
|
||||
entry = ldap.get_entry(dn)
|
||||
sid = entry['ipanttrusteddomainsid'][0]
|
||||
sid = entry.single_value.get('ipanttrusteddomainsid', None)
|
||||
if sid in trust_entry['ipantsidblacklistincoming']:
|
||||
trust_entry['ipantsidblacklistincoming'].remove(sid)
|
||||
ldap.update_entry(trust_entry)
|
||||
@@ -1735,7 +1766,7 @@ class trustdomain_disable(LDAPQuery):
|
||||
dn = self.obj.get_dn(keys[0], keys[1], trust_type=u'ad')
|
||||
try:
|
||||
entry = ldap.get_entry(dn)
|
||||
sid = entry['ipanttrusteddomainsid'][0]
|
||||
sid = entry.single_value.get('ipanttrusteddomainsid', None)
|
||||
if not (sid in trust_entry['ipantsidblacklistincoming']):
|
||||
trust_entry['ipantsidblacklistincoming'].append(sid)
|
||||
ldap.update_entry(trust_entry)
|
||||
|
||||
Reference in New Issue
Block a user