summaryrefslogtreecommitdiffstats
path: root/ipaserver/plugins
diff options
context:
space:
mode:
authorAlexander Bokovoy <abokovoy@redhat.com>2016-06-06 11:41:46 +0300
committerMartin Basti <mbasti@redhat.com>2016-06-11 17:25:50 +0200
commitbb75f5a5836ea011b8920f8bb8d58c1f4cd9b4c8 (patch)
tree108fedb3d09df8b2030e66702d3d3c2b4aaf701f /ipaserver/plugins
parentb506fd178edbf1553ca581c44ac6697f88ead125 (diff)
downloadfreeipa-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/plugins')
-rw-r--r--ipaserver/plugins/trust.py69
1 files changed, 50 insertions, 19 deletions
diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
index 8fd663b77..f9b48f3a3 100644
--- a/ipaserver/plugins/trust.py
+++ b/ipaserver/plugins/trust.py
@@ -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)