diff options
author | Alexander Bokovoy <abokovoy@redhat.com> | 2016-06-06 11:41:46 +0300 |
---|---|---|
committer | Martin Basti <mbasti@redhat.com> | 2016-06-11 17:25:50 +0200 |
commit | bb75f5a5836ea011b8920f8bb8d58c1f4cd9b4c8 (patch) | |
tree | 108fedb3d09df8b2030e66702d3d3c2b4aaf701f /ipaserver/dcerpc.py | |
parent | b506fd178edbf1553ca581c44ac6697f88ead125 (diff) | |
download | freeipa-bb75f5a5836ea011b8920f8bb8d58c1f4cd9b4c8.tar.gz freeipa-bb75f5a5836ea011b8920f8bb8d58c1f4cd9b4c8.tar.xz freeipa-bb75f5a5836ea011b8920f8bb8d58c1f4cd9b4c8.zip |
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>
Diffstat (limited to 'ipaserver/dcerpc.py')
-rw-r--r-- | ipaserver/dcerpc.py | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py index e1921dc0c..f0f5a0d71 100644 --- a/ipaserver/dcerpc.py +++ b/ipaserver/dcerpc.py @@ -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 |