403b09
From a9a73b0e0b601767324d5b6747b6ba46b6e5e90f Mon Sep 17 00:00:00 2001
403b09
From: Alexander Bokovoy <abokovoy@redhat.com>
403b09
Date: Tue, 7 Jun 2016 22:41:10 +0300
403b09
Subject: [PATCH] ipaserver/dcerpc: reformat to make the code closer to pep8
403b09
403b09
Because Samba Python bindings provide long-named methods and constants,
403b09
sometimes it is impossible to fit into 80 columns without causing
403b09
damage to readability of the code. This patchset attempts to reduce
403b09
pep8 complaints to a minimum.
403b09
403b09
https://fedorahosted.org/freeipa/ticket/6076
403b09
403b09
Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
403b09
---
403b09
 ipaserver/dcerpc.py | 473 +++++++++++++++++++++++++++++++++-------------------
403b09
 1 file changed, 298 insertions(+), 175 deletions(-)
403b09
403b09
diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
403b09
index 21ac89dfd71271ed384b875f95054d7ad1c0556d..19be6bf7a3617a3b867d51a9358c9926e91049a7 100644
403b09
--- a/ipaserver/dcerpc.py
403b09
+++ b/ipaserver/dcerpc.py
403b09
@@ -44,10 +44,12 @@ import samba
403b09
 import random
403b09
 from cryptography.hazmat.primitives.ciphers import Cipher, algorithms
403b09
 from cryptography.hazmat.backends import default_backend
403b09
+# pylint: disable=F0401
403b09
 try:
403b09
-    from ldap.controls import RequestControl as LDAPControl #pylint: disable=F0401
403b09
+    from ldap.controls import RequestControl as LDAPControl
403b09
 except ImportError:
403b09
-    from ldap.controls import LDAPControl as LDAPControl    #pylint: disable=F0401
403b09
+    from ldap.controls import LDAPControl as LDAPControl
403b09
+# pylint: enable=F0401
403b09
 import ldap as _ldap
403b09
 from ipapython.ipaldap import IPAdmin
403b09
 from ipaserver.session import krbccache_dir, krbccache_prefix
403b09
@@ -74,7 +76,7 @@ and Samba4 python bindings.
403b09
 
403b09
 # Both constants can be used as masks against trust direction
403b09
 # because bi-directional has two lower bits set.
403b09
-TRUST_ONEWAY        = 1
403b09
+TRUST_ONEWAY = 1
403b09
 TRUST_BIDIRECTIONAL = 3
403b09
 
403b09
 # Trust join behavior
403b09
@@ -91,31 +93,44 @@ def is_sid_valid(sid):
403b09
         return True
403b09
 
403b09
 
403b09
-access_denied_error =  errors.ACIError(info=_('CIFS server denied your credentials'))
403b09
+access_denied_error = errors.ACIError(
403b09
+                          info=_('CIFS server denied your credentials'))
403b09
 dcerpc_error_codes = {
403b09
     -1073741823:
403b09
-        errors.RemoteRetrieveError(reason=_('communication with CIFS server was unsuccessful')),
403b09
+        errors.RemoteRetrieveError(
403b09
+            reason=_('communication with CIFS server was unsuccessful')),
403b09
     -1073741790: access_denied_error,
403b09
     -1073741715: access_denied_error,
403b09
     -1073741614: access_denied_error,
403b09
     -1073741603:
403b09
-        errors.ValidationError(name=_('AD domain controller'), error=_('unsupported functional level')),
403b09
-    -1073741811: # NT_STATUS_INVALID_PARAMETER
403b09
+        errors.ValidationError(
403b09
+            name=_('AD domain controller'),
403b09
+            error=_('unsupported functional level')),
403b09
+    -1073741811:  # NT_STATUS_INVALID_PARAMETER
403b09
         errors.RemoteRetrieveError(
403b09
-            reason=_('AD domain controller complains about communication sequence. It may mean unsynchronized time on both sides, for example')),
403b09
-    -1073741776: # NT_STATUS_INVALID_PARAMETER_MIX, we simply will skip the binding
403b09
+            reason=_('AD domain controller complains about communication '
403b09
+                     'sequence. It may mean unsynchronized time on both '
403b09
+                     'sides, for example')),
403b09
+    -1073741776:  # NT_STATUS_INVALID_PARAMETER_MIX,
403b09
+                  # we simply will skip the binding
403b09
         access_denied_error,
403b09
-    -1073741772: # NT_STATUS_OBJECT_NAME_NOT_FOUND
403b09
-        errors.RemoteRetrieveError(reason=_('CIFS server configuration does not allow access to \\\\pipe\\lsarpc')),
403b09
+    -1073741772:  # NT_STATUS_OBJECT_NAME_NOT_FOUND
403b09
+        errors.RemoteRetrieveError(
403b09
+            reason=_('CIFS server configuration does not allow '
403b09
+                     'access to \\\\pipe\\lsarpc')),
403b09
 }
403b09
 
403b09
 dcerpc_error_messages = {
403b09
     "NT_STATUS_OBJECT_NAME_NOT_FOUND":
403b09
-         errors.NotFound(reason=_('Cannot find specified domain or server name')),
403b09
+        errors.NotFound(
403b09
+            reason=_('Cannot find specified domain or server name')),
403b09
     "WERR_NO_LOGON_SERVERS":
403b09
-         errors.RemoteRetrieveError(reason=_('AD DC was unable to reach any IPA domain controller. Most likely it is a DNS or firewall issue')),
403b09
+        errors.RemoteRetrieveError(
403b09
+            reason=_('AD DC was unable to reach any IPA domain controller. '
403b09
+                     'Most likely it is a DNS or firewall issue')),
403b09
     "NT_STATUS_INVALID_PARAMETER_MIX":
403b09
-         errors.RequirementError(name=_('At least the domain or IP address should be specified')),
403b09
+        errors.RequirementError(
403b09
+            name=_('At least the domain or IP address should be specified')),
403b09
 }
403b09
 
403b09
 pysss_type_key_translation_dict = {
403b09
@@ -126,7 +141,7 @@ pysss_type_key_translation_dict = {
403b09
 }
403b09
 
403b09
 
403b09
-def assess_dcerpc_exception(num=None,message=None):
403b09
+def assess_dcerpc_exception(num=None, message=None):
403b09
     """
403b09
     Takes error returned by Samba bindings and converts it into
403b09
     an IPA error class.
403b09
@@ -135,8 +150,9 @@ def assess_dcerpc_exception(num=None,message=None):
403b09
         return dcerpc_error_codes[num]
403b09
     if message and message in dcerpc_error_messages:
403b09
         return dcerpc_error_messages[message]
403b09
-    reason = _('''CIFS server communication error: code "%(num)s",
403b09
-                  message "%(message)s" (both may be "None")''') % dict(num=num, message=message)
403b09
+    reason = _('CIFS server communication error: code "%(num)s", '
403b09
+               'message "%(message)s" (both may be "None")') % \
403b09
+        dict(num=num, message=message)
403b09
     return errors.RemoteRetrieveError(reason=reason)
403b09
 
403b09
 
403b09
@@ -182,9 +198,13 @@ class DomainValidator(object):
403b09
         self._parm = None
403b09
 
403b09
     def is_configured(self):
403b09
-        cn_trust_local = DN(('cn', self.api.env.domain), self.api.env.container_cifsdomains, self.api.env.basedn)
403b09
+        cn_trust_local = DN(('cn', self.api.env.domain),
403b09
+                            self.api.env.container_cifsdomains,
403b09
+                            self.api.env.basedn)
403b09
         try:
403b09
-            entry_attrs = self.ldap.get_entry(cn_trust_local, [self.ATTR_FLATNAME, self.ATTR_SID])
403b09
+            entry_attrs = self.ldap.get_entry(cn_trust_local,
403b09
+                                              [self.ATTR_FLATNAME,
403b09
+                                               self.ATTR_SID])
403b09
             self.flatname = entry_attrs[self.ATTR_FLATNAME][0]
403b09
             self.sid = entry_attrs[self.ATTR_SID][0]
403b09
             self.dn = entry_attrs.dn
403b09
@@ -203,7 +223,8 @@ class DomainValidator(object):
403b09
 
403b09
         try:
403b09
             search_kw = {'objectClass': 'ipaNTTrustedDomain'}
403b09
-            filter = self.ldap.make_filter(search_kw, rules=self.ldap.MATCH_ALL)
403b09
+            filter = self.ldap.make_filter(search_kw,
403b09
+                                           rules=self.ldap.MATCH_ALL)
403b09
             (entries, truncated) = self.ldap.find_entries(
403b09
                 filter=filter,
403b09
                 base_dn=cn_trust,
403b09
@@ -216,22 +237,22 @@ class DomainValidator(object):
403b09
             # domain names as keys and those are generally case-insensitive
403b09
             result = ipautil.CIDict()
403b09
 
403b09
-            for entry in entries:
403b09
+            for e in entries:
403b09
                 try:
403b09
-                    trust_partner = entry[self.ATTR_TRUST_PARTNER][0]
403b09
-                    flatname_normalized = entry[self.ATTR_FLATNAME][0].lower()
403b09
-                    trusted_sid = entry[self.ATTR_TRUSTED_SID][0]
403b09
-                except KeyError as e:
403b09
+                    t_partner = e.single_value.get(self.ATTR_TRUST_PARTNER)
403b09
+                    fname_norm = e.single_value.get(self.ATTR_FLATNAME).lower()
403b09
+                    trusted_sid = e.single_value.get(self.ATTR_TRUSTED_SID)
403b09
+                except KeyError as exc:
403b09
                     # Some piece of trusted domain info in LDAP is missing
403b09
                     # Skip the domain, but leave log entry for investigation
403b09
                     api.log.warning("Trusted domain '%s' entry misses an "
403b09
-                                 "attribute: %s", entry.dn, e)
403b09
+                                    "attribute: %s", e.dn, exc)
403b09
                     continue
403b09
 
403b09
-                result[trust_partner] = (flatname_normalized,
403b09
-                                         security.dom_sid(trusted_sid))
403b09
+                result[t_partner] = (fname_norm,
403b09
+                                     security.dom_sid(trusted_sid))
403b09
             return result
403b09
-        except errors.NotFound as e:
403b09
+        except errors.NotFound as exc:
403b09
             return []
403b09
 
403b09
     def set_trusted_domains(self):
403b09
@@ -244,21 +265,22 @@ class DomainValidator(object):
403b09
             # This means we can't check the correctness of a trusted
403b09
             # domain SIDs
403b09
             raise errors.ValidationError(name='sid',
403b09
-                  error=_('no trusted domain is configured'))
403b09
+                                         error=_('no trusted domain '
403b09
+                                                 'is configured'))
403b09
 
403b09
     def get_domain_by_sid(self, sid, exact_match=False):
403b09
         if not self.domain:
403b09
             # our domain is not configured or self.is_configured() never run
403b09
             # reject SIDs as we can't check correctness of them
403b09
             raise errors.ValidationError(name='sid',
403b09
-                  error=_('domain is not configured'))
403b09
+                                         error=_('domain is not configured'))
403b09
 
403b09
         # Parse sid string to see if it is really in a SID format
403b09
         try:
403b09
             test_sid = security.dom_sid(sid)
403b09
         except TypeError:
403b09
             raise errors.ValidationError(name='sid',
403b09
-                  error=_('SID is not valid'))
403b09
+                                         error=_('SID is not valid'))
403b09
 
403b09
         # At this point we have SID_NT_AUTHORITY family SID and really need to
403b09
         # check it against prefixes of domain SIDs we trust to
403b09
@@ -314,30 +336,34 @@ class DomainValidator(object):
403b09
             return None
403b09
 
403b09
     def get_trusted_domain_objects(self, domain=None, flatname=None, filter="",
403b09
-            attrs=None, scope=_ldap.SCOPE_SUBTREE, basedn=None):
403b09
+                                   attrs=None, scope=_ldap.SCOPE_SUBTREE,
403b09
+                                   basedn=None):
403b09
         """
403b09
-        Search for LDAP objects in a trusted domain specified either by `domain'
403b09
-        or `flatname'. The actual LDAP search is specified by `filter', `attrs',
403b09
-        `scope' and `basedn'. When `basedn' is empty, database root DN is used.
403b09
+        Search for LDAP objects in a trusted domain specified either by
403b09
+        `domain' or `flatname'. The actual LDAP search is specified by
403b09
+        `filter', `attrs', `scope' and `basedn'. When `basedn' is empty,
403b09
+        database root DN is used.
403b09
         """
403b09
         assert domain is not None or flatname is not None
403b09
         """Returns SID for the trusted domain object (user or group only)"""
403b09
         if not self.domain:
403b09
             # our domain is not configured or self.is_configured() never run
403b09
             raise errors.ValidationError(name=_('Trust setup'),
403b09
-                error=_('Our domain is not configured'))
403b09
+                                         error=_('Our domain is '
403b09
+                                                 'not configured'))
403b09
         if not self._domains:
403b09
             self._domains = self.get_trusted_domains()
403b09
         if len(self._domains) == 0:
403b09
             # Our domain is configured but no trusted domains are configured
403b09
             raise errors.ValidationError(name=_('Trust setup'),
403b09
-                error=_('No trusted domain is not configured'))
403b09
+                                         error=_('No trusted domain is '
403b09
+                                                 'not configured'))
403b09
 
403b09
         entries = None
403b09
         if domain is not None:
403b09
             if domain not in self._domains:
403b09
                 raise errors.ValidationError(name=_('trusted domain object'),
403b09
-                   error= _('domain is not trusted'))
403b09
+                                             error=_('domain is not trusted'))
403b09
             # Now we have a name to check against our list of trusted domains
403b09
             entries = self.search_in_dc(domain, filter, attrs, scope, basedn)
403b09
         elif flatname is not None:
403b09
@@ -347,53 +373,65 @@ class DomainValidator(object):
403b09
             for domain in self._domains:
403b09
                 if self._domains[domain][0] == flatname:
403b09
                     found_flatname = True
403b09
-                    entries = self.search_in_dc(domain, filter, attrs, scope, basedn)
403b09
+                    entries = self.search_in_dc(domain, filter,
403b09
+                                                attrs, scope, basedn)
403b09
                     if entries:
403b09
                         break
403b09
             if not found_flatname:
403b09
                 raise errors.ValidationError(name=_('trusted domain object'),
403b09
-                        error= _('no trusted domain matched the specified flat name'))
403b09
+                                             error=_('no trusted domain '
403b09
+                                                     'matched the specified '
403b09
+                                                     'flat name'))
403b09
         if not entries:
403b09
             raise errors.NotFound(reason=_('trusted domain object not found'))
403b09
 
403b09
         return entries
403b09
 
403b09
-    def get_trusted_domain_object_sid(self, object_name, fallback_to_ldap=True):
403b09
+    def get_trusted_domain_object_sid(self, object_name,
403b09
+                                      fallback_to_ldap=True):
403b09
         result = pysss_nss_idmap.getsidbyname(object_name)
403b09
-        if object_name in result and (pysss_nss_idmap.SID_KEY in result[object_name]):
403b09
+        if object_name in result and \
403b09
+           (pysss_nss_idmap.SID_KEY in result[object_name]):
403b09
             object_sid = result[object_name][pysss_nss_idmap.SID_KEY]
403b09
             return object_sid
403b09
 
403b09
         # If fallback to AD DC LDAP is not allowed, bail out
403b09
         if not fallback_to_ldap:
403b09
             raise errors.ValidationError(name=_('trusted domain object'),
403b09
-               error= _('SSSD was unable to resolve the object to a valid SID'))
403b09
+                                         error=_('SSSD was unable to resolve '
403b09
+                                                 'the object to a valid SID'))
403b09
 
403b09
         # Else, we are going to contact AD DC LDAP
403b09
         components = normalize_name(object_name)
403b09
         if not ('domain' in components or 'flatname' in components):
403b09
             # No domain or realm specified, ambiguous search
403b09
-             raise errors.ValidationError(name=_('trusted domain object'),
403b09
-                   error= _('Ambiguous search, user domain was not specified'))
403b09
+            raise errors.ValidationError(name=_('trusted domain object'),
403b09
+                                         error=_('Ambiguous search, user '
403b09
+                                                 'domain was not specified'))
403b09
 
403b09
         attrs = ['objectSid']
403b09
-        filter = '(&(sAMAccountName=%(name)s)(|(objectClass=user)(objectClass=group)))' \
403b09
-                % dict(name=components['name'])
403b09
+        filter = '(&(sAMAccountName=%(name)s)' \
403b09
+                 '(|(objectClass=user)(objectClass=group)))' \
403b09
+                 % dict(name=components['name'])
403b09
         scope = _ldap.SCOPE_SUBTREE
403b09
         entries = self.get_trusted_domain_objects(components.get('domain'),
403b09
-                components.get('flatname'), filter, attrs, scope)
403b09
+                                                  components.get('flatname'),
403b09
+                                                  filter, attrs, scope)
403b09
 
403b09
         if len(entries) > 1:
403b09
             # Treat non-unique entries as invalid
403b09
             raise errors.ValidationError(name=_('trusted domain object'),
403b09
-               error= _('Trusted domain did not return a unique object'))
403b09
+                                         error=_('Trusted domain did not '
403b09
+                                                 'return a unique object'))
403b09
         sid = self.__sid_to_str(entries[0]['objectSid'][0])
403b09
         try:
403b09
             test_sid = security.dom_sid(sid)
403b09
             return unicode(test_sid)
403b09
         except TypeError as e:
403b09
             raise errors.ValidationError(name=_('trusted domain object'),
403b09
-               error= _('Trusted domain did not return a valid SID for the object'))
403b09
+                                         error=_('Trusted domain did not '
403b09
+                                                 'return a valid SID for '
403b09
+                                                 'the object'))
403b09
 
403b09
     def get_trusted_domain_object_type(self, name_or_sid):
403b09
         """
403b09
@@ -443,7 +481,8 @@ class DomainValidator(object):
403b09
         )
403b09
 
403b09
         attrs = ['sAMAccountName']
403b09
-        filter = (r'(&(objectSid=%(sid)s)(|(objectClass=user)(objectClass=group)))'
403b09
+        filter = (r'(&(objectSid=%(sid)s)'
403b09
+                  '(|(objectClass=user)(objectClass=group)))'
403b09
                   % dict(sid=escaped_sid))  # sid in binary
403b09
         domain = self.get_domain_by_sid(sid)
403b09
 
403b09
@@ -454,7 +493,8 @@ class DomainValidator(object):
403b09
         if len(entries) > 1:
403b09
             # Treat non-unique entries as invalid
403b09
             raise errors.ValidationError(name=_('trusted domain object'),
403b09
-               error=_('Trusted domain did not return a unique object'))
403b09
+                                         error=_('Trusted domain did not '
403b09
+                                                 'return a unique object'))
403b09
 
403b09
         object_name = (
403b09
             "%s@%s" % (entries[0].single_value['sAMAccountName'].lower(),
403b09
@@ -486,27 +526,31 @@ class DomainValidator(object):
403b09
             # Now search a trusted domain for a user with this SID
403b09
             attrs = ['cn']
403b09
             filter = '(&(objectClass=user)(objectSid=%(sid)s))' \
403b09
-                    % dict(sid=object_name)
403b09
+                % dict(sid=object_name)
403b09
             try:
403b09
-                entries = self.get_trusted_domain_objects(domain=domain, filter=filter,
403b09
-                        attrs=attrs, scope=_ldap.SCOPE_SUBTREE)
403b09
+                entries = self.get_trusted_domain_objects(domain=domain,
403b09
+                                                          filter=filter,
403b09
+                                                          attrs=attrs,
403b09
+                                                          scope=_ldap.SCOPE_SUBTREE)
403b09
             except errors.NotFound:
403b09
                 raise errors.NotFound(reason=_('trusted domain user not found'))
403b09
             user_dn = entries[0].dn
403b09
         elif domain or flatname:
403b09
             attrs = ['cn']
403b09
             filter = '(&(sAMAccountName=%(name)s)(objectClass=user))' \
403b09
-                    % dict(name=name)
403b09
+                     % dict(name=name)
403b09
             try:
403b09
                 entries = self.get_trusted_domain_objects(domain,
403b09
-                        flatname, filter, attrs, _ldap.SCOPE_SUBTREE)
403b09
+                                                          flatname, filter, attrs,
403b09
+                                                          _ldap.SCOPE_SUBTREE)
403b09
             except errors.NotFound:
403b09
                 raise errors.NotFound(reason=_('trusted domain user not found'))
403b09
             user_dn = entries[0].dn
403b09
         else:
403b09
             # No domain or realm specified, ambiguous search
403b09
             raise errors.ValidationError(name=_('trusted domain object'),
403b09
-                   error= _('Ambiguous search, user domain was not specified'))
403b09
+                                         error=_('Ambiguous search, '
403b09
+                                                 'user domain was not specified'))
403b09
 
403b09
         # Get SIDs of user object and it's groups
403b09
         # tokenGroups attribute must be read with a scope BASE for a known user
403b09
@@ -514,9 +558,11 @@ class DomainValidator(object):
403b09
         attrs = ['objectSID', 'tokenGroups']
403b09
         filter = "(objectClass=user)"
403b09
         entries = self.get_trusted_domain_objects(domain,
403b09
-            flatname, filter, attrs, _ldap.SCOPE_BASE, user_dn)
403b09
+                                                  flatname, filter, attrs,
403b09
+                                                  _ldap.SCOPE_BASE, user_dn)
403b09
         object_sid = self.__sid_to_str(entries[0]['objectSid'][0])
403b09
-        group_sids = [self.__sid_to_str(sid) for sid in entries[0]['tokenGroups']]
403b09
+        group_sids = [self.__sid_to_str(sid)
403b09
+                      for sid in entries[0]['tokenGroups']]
403b09
         return (object_sid, group_sids)
403b09
 
403b09
     def get_trusted_domain_user_and_groups(self, object_name):
403b09
@@ -540,11 +586,14 @@ class DomainValidator(object):
403b09
         if is_valid_sid:
403b09
             object_sid = object_name
403b09
             result = pysss_nss_idmap.getnamebysid(object_name)
403b09
-            if object_name in result and (pysss_nss_idmap.NAME_KEY in result[object_name]):
403b09
-                group_list = pysss.getgrouplist(result[object_name][pysss_nss_idmap.NAME_KEY])
403b09
+            if object_name in result and \
403b09
+               (pysss_nss_idmap.NAME_KEY in result[object_name]):
403b09
+                group_list = pysss.getgrouplist(
403b09
+                                 result[object_name][pysss_nss_idmap.NAME_KEY])
403b09
         else:
403b09
             result = pysss_nss_idmap.getsidbyname(object_name)
403b09
-            if object_name in result and (pysss_nss_idmap.SID_KEY in result[object_name]):
403b09
+            if object_name in result and \
403b09
+               (pysss_nss_idmap.SID_KEY in result[object_name]):
403b09
                 object_sid = result[object_name][pysss_nss_idmap.SID_KEY]
403b09
                 group_list = pysss.getgrouplist(object_name)
403b09
 
403b09
@@ -552,7 +601,10 @@ class DomainValidator(object):
403b09
             return self.__get_trusted_domain_user_and_groups(object_name)
403b09
 
403b09
         group_sids = pysss_nss_idmap.getsidbyname(group_list)
403b09
-        return (object_sid, [el[1][pysss_nss_idmap.SID_KEY] for el in group_sids.items()])
403b09
+        return (
403b09
+                object_sid,
403b09
+                [el[1][pysss_nss_idmap.SID_KEY] for el in group_sids.items()]
403b09
+               )
403b09
 
403b09
     def __sid_to_str(self, sid):
403b09
         """
403b09
@@ -561,12 +613,13 @@ class DomainValidator(object):
403b09
         """
403b09
         sid_rev_num = ord(sid[0])
403b09
         number_sub_id = ord(sid[1])
403b09
-        ia = struct.unpack('!Q','\x00\x00'+sid[2:8])[0]
403b09
+        ia = struct.unpack('!Q', '\x00\x00'+sid[2:8])[0]
403b09
         subs = [
403b09
-            struct.unpack('
403b09
+            struct.unpack('
403b09
             for i in range(number_sub_id)
403b09
         ]
403b09
-        return u'S-%d-%d-%s' % ( sid_rev_num, ia, '-'.join([str(s) for s in subs]),)
403b09
+        return u'S-%d-%d-%s' % (sid_rev_num, ia,
403b09
+                                '-'.join([str(s) for s in subs]),)
403b09
 
403b09
     def kinit_as_http(self, domain):
403b09
         """
403b09
@@ -624,7 +677,7 @@ class DomainValidator(object):
403b09
         error on ccache initialization
403b09
         """
403b09
 
403b09
-        if self._admin_creds == None:
403b09
+        if self._admin_creds is None:
403b09
             return (None, None)
403b09
 
403b09
         domain_suffix = domain.replace('.', '-')
403b09
@@ -691,7 +744,8 @@ class DomainValidator(object):
403b09
         ccache_name = None
403b09
 
403b09
         if self._admin_creds:
403b09
-            (ccache_name, principal) = self.kinit_as_administrator(info['dns_domain'])
403b09
+            (ccache_name,
403b09
+             principal) = self.kinit_as_administrator(info['dns_domain'])
403b09
 
403b09
         if ccache_name:
403b09
             with ipautil.private_ccache(path=ccache_name):
403b09
@@ -736,7 +790,7 @@ class DomainValidator(object):
403b09
 
403b09
         if not self._creds:
403b09
             self._parm = param.LoadParm()
403b09
-            self._parm.load(os.path.join(ipautil.SHARE_DIR,"smb.conf.empty"))
403b09
+            self._parm.load(os.path.join(ipautil.SHARE_DIR, "smb.conf.empty"))
403b09
             self._parm.set('netbios name', self.flatname)
403b09
             self._creds = credentials.Credentials()
403b09
             self._creds.set_kerberos_state(credentials.MUST_USE_KERBEROS)
403b09
@@ -746,12 +800,14 @@ class DomainValidator(object):
403b09
         netrc = net.Net(creds=self._creds, lp=self._parm)
403b09
         finddc_error = None
403b09
         result = None
403b09
+        flags = nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_GC | nbt.NBT_SERVER_CLOSEST
403b09
         try:
403b09
-            result = netrc.finddc(domain=domain, flags=nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_GC | nbt.NBT_SERVER_CLOSEST)
403b09
+            result = netrc.finddc(domain=domain, flags=flags)
403b09
         except RuntimeError as e:
403b09
             try:
403b09
                 # If search of closest GC failed, attempt to find any one
403b09
-                result = netrc.finddc(domain=domain, flags=nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_GC)
403b09
+                flags = nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_GC
403b09
+                result = netrc.finddc(domain=domain, flags=flags)
403b09
             except RuntimeError as e:
403b09
                 finddc_error = e
403b09
 
403b09
@@ -789,6 +845,7 @@ class DomainValidator(object):
403b09
         self._info[domain] = info
403b09
         return info
403b09
 
403b09
+
403b09
 def string_to_array(what):
403b09
     return [ord(v) for v in what]
403b09
 
403b09
@@ -797,7 +854,7 @@ class TrustDomainInstance(object):
403b09
 
403b09
     def __init__(self, hostname, creds=None):
403b09
         self.parm = param.LoadParm()
403b09
-        self.parm.load(os.path.join(ipautil.SHARE_DIR,"smb.conf.empty"))
403b09
+        self.parm.load(os.path.join(ipautil.SHARE_DIR, "smb.conf.empty"))
403b09
         if len(hostname) > 0:
403b09
             self.parm.set('netbios name', hostname)
403b09
         self.creds = creds
403b09
@@ -810,14 +867,14 @@ class TrustDomainInstance(object):
403b09
         self.validation_attempts = 0
403b09
 
403b09
     def __gen_lsa_connection(self, binding):
403b09
-       if self.creds is None:
403b09
-           raise errors.RequirementError(name=_('CIFS credentials object'))
403b09
-       try:
403b09
-           result = lsa.lsarpc(binding, self.parm, self.creds)
403b09
-           return result
403b09
-       except RuntimeError as e:
403b09
-           num, message = e.args  # pylint: disable=unpacking-non-sequence
403b09
-           raise assess_dcerpc_exception(num=num, message=message)
403b09
+        if self.creds is None:
403b09
+            raise errors.RequirementError(name=_('CIFS credentials object'))
403b09
+        try:
403b09
+            result = lsa.lsarpc(binding, self.parm, self.creds)
403b09
+            return result
403b09
+        except RuntimeError as e:
403b09
+            num, message = e.args  # pylint: disable=unpacking-non-sequence
403b09
+            raise assess_dcerpc_exception(num=num, message=message)
403b09
 
403b09
     def init_lsa_pipe(self, remote_host):
403b09
         """
403b09
@@ -847,30 +904,35 @@ class TrustDomainInstance(object):
403b09
                 # When session key is not available, we just skip this binding
403b09
                 session_attempts = session_attempts + 1
403b09
 
403b09
-        if self._pipe is None and (attempts + session_attempts) == len(bindings):
403b09
+        if self._pipe is None and \
403b09
+           (attempts + session_attempts) == len(bindings):
403b09
             raise errors.ACIError(
403b09
-                info=_('CIFS server %(host)s denied your credentials') % dict(host=remote_host))
403b09
+                      info=_('CIFS server %(host)s denied your credentials')
403b09
+                      % dict(host=remote_host))
403b09
 
403b09
         if self._pipe is None:
403b09
             raise errors.RemoteRetrieveError(
403b09
-                reason=_('Cannot establish LSA connection to %(host)s. Is CIFS server running?') % dict(host=remote_host))
403b09
+                    reason=_('Cannot establish LSA connection to %(host)s. '
403b09
+                             'Is CIFS server running?') % dict(host=remote_host))
403b09
         self.binding = binding
403b09
         self.session_key = self._pipe.session_key
403b09
 
403b09
     def __gen_lsa_bindings(self, remote_host):
403b09
         """
403b09
-        There are multiple transports to issue LSA calls. However, depending on a
403b09
-        system in use they may be blocked by local operating system policies.
403b09
+        There are multiple transports to issue LSA calls. However, depending on
403b09
+        a system in use they may be blocked by local operating system policies.
403b09
         Generate all we can use. init_lsa_pipe() will try them one by one until
403b09
         there is one working.
403b09
 
403b09
-        We try NCACN_NP before NCACN_IP_TCP and use SMB2 before SMB1 or defaults.
403b09
+        We try NCACN_NP before NCACN_IP_TCP and use SMB2 before SMB1.
403b09
         """
403b09
         transports = (u'ncacn_np', u'ncacn_ip_tcp')
403b09
-        options = ( u'smb2,print', u'print')
403b09
-        return [u'%s:%s[%s]' % (t, remote_host, o) for t in transports for o in options]
403b09
+        options = (u'smb2,print', u'print')
403b09
+        return [u'%s:%s[%s]' % (t, remote_host, o)
403b09
+                for t in transports for o in options]
403b09
 
403b09
-    def retrieve_anonymously(self, remote_host, discover_srv=False, search_pdc=False):
403b09
+    def retrieve_anonymously(self, remote_host,
403b09
+                             discover_srv=False, search_pdc=False):
403b09
         """
403b09
         When retrieving DC information anonymously, we can't get SID of the domain
403b09
         """
403b09
@@ -896,7 +958,8 @@ class TrustDomainInstance(object):
403b09
         self.info['is_pdc'] = (result.server_type & nbt.NBT_SERVER_PDC) != 0
403b09
 
403b09
         # Netlogon response doesn't contain SID of the domain.
403b09
-        # We need to do rootDSE search with LDAP_SERVER_EXTENDED_DN_OID control to reveal the SID
403b09
+        # We need to do rootDSE search with LDAP_SERVER_EXTENDED_DN_OID
403b09
+        # control to reveal the SID
403b09
         ldap_uri = 'ldap://%s' % (result.pdc_dns_name)
403b09
         conn = _ldap.initialize(ldap_uri)
403b09
         conn.set_option(_ldap.OPT_SERVER_CONTROLS, [ExtendedDNControl()])
403b09
@@ -908,7 +971,7 @@ class TrustDomainInstance(object):
403b09
         except _ldap.LDAPError as e:
403b09
             root_logger.error(
403b09
                 "LDAP error when connecting to %(host)s: %(error)s" %
403b09
-                    dict(host=unicode(result.pdc_name), error=str(e)))
403b09
+                dict(host=unicode(result.pdc_name), error=str(e)))
403b09
         except KeyError as e:
403b09
             root_logger.error("KeyError: {err}, LDAP entry from {host} "
403b09
                               "returned malformed. Your DNS might be "
403b09
@@ -930,8 +993,11 @@ class TrustDomainInstance(object):
403b09
         objectAttribute = lsa.ObjectAttribute()
403b09
         objectAttribute.sec_qos = lsa.QosInfo()
403b09
         try:
403b09
-            self._policy_handle = self._pipe.OpenPolicy2(u"", objectAttribute, security.SEC_FLAG_MAXIMUM_ALLOWED)
403b09
-            result = self._pipe.QueryInfoPolicy2(self._policy_handle, lsa.LSA_POLICY_INFO_DNS)
403b09
+            self._policy_handle = \
403b09
+                self._pipe.OpenPolicy2(u"", objectAttribute,
403b09
+                                       security.SEC_FLAG_MAXIMUM_ALLOWED)
403b09
+            result = self._pipe.QueryInfoPolicy2(self._policy_handle,
403b09
+                                                 lsa.LSA_POLICY_INFO_DNS)
403b09
         except RuntimeError as e:
403b09
             num, message = e.args  # pylint: disable=unpacking-non-sequence
403b09
             raise assess_dcerpc_exception(num=num, message=message)
403b09
@@ -944,7 +1010,8 @@ class TrustDomainInstance(object):
403b09
         self.info['dc'] = remote_host
403b09
 
403b09
         try:
403b09
-            result = self._pipe.QueryInfoPolicy2(self._policy_handle, lsa.LSA_POLICY_INFO_ROLE)
403b09
+            result = self._pipe.QueryInfoPolicy2(self._policy_handle,
403b09
+                                                 lsa.LSA_POLICY_INFO_ROLE)
403b09
         except RuntimeError as e:
403b09
             num, message = e.args  # pylint: disable=unpacking-non-sequence
403b09
             raise assess_dcerpc_exception(num=num, message=message)
403b09
@@ -958,18 +1025,18 @@ class TrustDomainInstance(object):
403b09
         clear_value.size = len(password_blob)
403b09
         clear_value.password = password_blob
403b09
 
403b09
-        clear_authentication_information = drsblobs.AuthenticationInformation()
403b09
-        clear_authentication_information.LastUpdateTime = samba.unix2nttime(int(time.time()))
403b09
-        clear_authentication_information.AuthType = lsa.TRUST_AUTH_TYPE_CLEAR
403b09
-        clear_authentication_information.AuthInfo = clear_value
403b09
+        clear_authinfo = drsblobs.AuthenticationInformation()
403b09
+        clear_authinfo.LastUpdateTime = samba.unix2nttime(int(time.time()))
403b09
+        clear_authinfo.AuthType = lsa.TRUST_AUTH_TYPE_CLEAR
403b09
+        clear_authinfo.AuthInfo = clear_value
403b09
 
403b09
-        authentication_information_array = drsblobs.AuthenticationInformationArray()
403b09
-        authentication_information_array.count = 1
403b09
-        authentication_information_array.array = [clear_authentication_information]
403b09
+        authinfo_array = drsblobs.AuthenticationInformationArray()
403b09
+        authinfo_array.count = 1
403b09
+        authinfo_array.array = [clear_authinfo]
403b09
 
403b09
         outgoing = drsblobs.trustAuthInOutBlob()
403b09
         outgoing.count = 1
403b09
-        outgoing.current = authentication_information_array
403b09
+        outgoing.current = authinfo_array
403b09
 
403b09
         confounder = [3]*512
403b09
         for i in range(512):
403b09
@@ -983,7 +1050,8 @@ class TrustDomainInstance(object):
403b09
 
403b09
         trustpass_blob = ndr_pack(trustpass)
403b09
 
403b09
-        encrypted_trustpass = arcfour_encrypt(self._pipe.session_key, trustpass_blob)
403b09
+        encrypted_trustpass = arcfour_encrypt(self._pipe.session_key,
403b09
+                                              trustpass_blob)
403b09
 
403b09
         auth_blob = lsa.DATA_BUF2()
403b09
         auth_blob.size = len(encrypted_trustpass)
403b09
@@ -993,7 +1061,6 @@ class TrustDomainInstance(object):
403b09
         auth_info.auth_blob = auth_blob
403b09
         self.auth_info = auth_info
403b09
 
403b09
-
403b09
     def generate_ftinfo(self, another_domain):
403b09
         """
403b09
         Generates TrustDomainInfoFullInfo2Internal structure
403b09
@@ -1032,27 +1099,38 @@ class TrustDomainInstance(object):
403b09
                 # smbd already has the information about itself
403b09
                 ldname = lsa.StringLarge()
403b09
                 ldname.string = another_domain.info['dns_domain']
403b09
-                collision_info = self._pipe.lsaRSetForestTrustInformation(self._policy_handle,
403b09
-                                                                          ldname,
403b09
-                                                                          lsa.LSA_FOREST_TRUST_DOMAIN_INFO,
403b09
-                                                                          ftinfo, 0)
403b09
-                if collision_info:
403b09
-                    root_logger.error("When setting forest trust information, got collision info back:\n%s" % (ndr_print(collision_info)))
403b09
+                ftlevel = lsa.LSA_FOREST_TRUST_DOMAIN_INFO
403b09
+                # RSetForestTrustInformation returns collision information
403b09
+                # for trust topology
403b09
+                cinfo = self._pipe.lsaRSetForestTrustInformation(
403b09
+                            self._policy_handle,
403b09
+                            ldname,
403b09
+                            ftlevel,
403b09
+                            ftinfo, 0)
403b09
+                if cinfo:
403b09
+                    root_logger.error("When setting forest trust information, "
403b09
+                                      "got collision info back:\n%s"
403b09
+                                      % (ndr_print(cinfo)))
403b09
         except RuntimeError as e:
403b09
-            # We can ignore the error here -- setting up name suffix routes may fail
403b09
+            # We can ignore the error here --
403b09
+            # setting up name suffix routes may fail
403b09
             pass
403b09
 
403b09
-    def establish_trust(self, another_domain, trustdom_secret, trust_type='bidirectional', trust_external=False):
403b09
+    def establish_trust(self, another_domain, trustdom_secret,
403b09
+                        trust_type='bidirectional', trust_external=False):
403b09
         """
403b09
         Establishes trust between our and another domain
403b09
-        Input: another_domain -- instance of TrustDomainInstance, initialized with #retrieve call
403b09
+        Input: another_domain -- instance of TrustDomainInstance,
403b09
+                                 initialized with #retrieve call
403b09
                trustdom_secret -- shared secred used for the trust
403b09
         """
403b09
         if self.info['name'] == another_domain.info['name']:
403b09
             # Check that NetBIOS names do not clash
403b09
             raise errors.ValidationError(name=u'AD Trust Setup',
403b09
-                    error=_('the IPA server and the remote domain cannot share the same '
403b09
-                            'NetBIOS name: %s') % self.info['name'])
403b09
+                                         error=_('the IPA server and the '
403b09
+                                                 'remote domain cannot share '
403b09
+                                                 'the same NetBIOS name: %s')
403b09
+                                         % self.info['name'])
403b09
 
403b09
         self.generate_auth(trustdom_secret)
403b09
 
403b09
@@ -1071,8 +1149,12 @@ class TrustDomainInstance(object):
403b09
         try:
403b09
             dname = lsa.String()
403b09
             dname.string = another_domain.info['dns_domain']
403b09
-            res = self._pipe.QueryTrustedDomainInfoByName(self._policy_handle, dname, lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO)
403b09
-            self._pipe.DeleteTrustedDomain(self._policy_handle, res.info_ex.sid)
403b09
+            res = self._pipe.QueryTrustedDomainInfoByName(
403b09
+                                self._policy_handle,
403b09
+                                dname,
403b09
+                                lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO)
403b09
+            self._pipe.DeleteTrustedDomain(self._policy_handle,
403b09
+                                           res.info_ex.sid)
403b09
         except RuntimeError as e:
403b09
             num, message = e.args  # pylint: disable=unpacking-non-sequence
403b09
             # Ignore anything but access denied (NT_STATUS_ACCESS_DENIED)
403b09
@@ -1080,7 +1162,10 @@ class TrustDomainInstance(object):
403b09
                 raise access_denied_error
403b09
 
403b09
         try:
403b09
-            trustdom_handle = self._pipe.CreateTrustedDomainEx2(self._policy_handle, info, self.auth_info, security.SEC_STD_DELETE)
403b09
+            trustdom_handle = self._pipe.CreateTrustedDomainEx2(
403b09
+                                           self._policy_handle,
403b09
+                                           info, self.auth_info,
403b09
+                                           security.SEC_STD_DELETE)
403b09
         except RuntimeError as e:
403b09
             num, message = e.args  # pylint: disable=unpacking-non-sequence
403b09
             raise assess_dcerpc_exception(num=num, message=message)
403b09
@@ -1089,13 +1174,19 @@ class TrustDomainInstance(object):
403b09
         # trust settings. Samba insists this has to be done with LSA
403b09
         # OpenTrustedDomain* calls, it is not enough to have a handle
403b09
         # returned by the CreateTrustedDomainEx2 call.
403b09
-        trustdom_handle = self._pipe.OpenTrustedDomainByName(self._policy_handle, dname, security.SEC_FLAG_MAXIMUM_ALLOWED)
403b09
+        trustdom_handle = self._pipe.OpenTrustedDomainByName(
403b09
+                                         self._policy_handle,
403b09
+                                         dname,
403b09
+                                         security.SEC_FLAG_MAXIMUM_ALLOWED)
403b09
         try:
403b09
-            infoclass = lsa.TrustDomainInfoSupportedEncTypes()
403b09
-            infoclass.enc_types = security.KERB_ENCTYPE_RC4_HMAC_MD5
403b09
-            infoclass.enc_types |= security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96
403b09
-            infoclass.enc_types |= security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96
403b09
-            self._pipe.SetInformationTrustedDomain(trustdom_handle, lsa.LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES, infoclass)
403b09
+            infocls = lsa.TrustDomainInfoSupportedEncTypes()
403b09
+            infocls.enc_types = security.KERB_ENCTYPE_RC4_HMAC_MD5
403b09
+            infocls.enc_types |= security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96
403b09
+            infocls.enc_types |= security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96
403b09
+            self._pipe.SetInformationTrustedDomain(
403b09
+                           trustdom_handle,
403b09
+                           lsa.LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES,
403b09
+                           infocls)
403b09
         except RuntimeError as e:
403b09
             # We can ignore the error here -- changing enctypes is for
403b09
             # improved security but the trust will work with default values as
403b09
@@ -1105,13 +1196,16 @@ class TrustDomainInstance(object):
403b09
 
403b09
         if not trust_external:
403b09
             try:
403b09
-                info = self._pipe.QueryTrustedDomainInfo(trustdom_handle,
403b09
-                                                         lsa.LSA_TRUSTED_DOMAIN_INFO_INFO_EX)
403b09
+                info = self._pipe.QueryTrustedDomainInfo(
403b09
+                                      trustdom_handle,
403b09
+                                      lsa.LSA_TRUSTED_DOMAIN_INFO_INFO_EX)
403b09
                 info.trust_attributes |= lsa.LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE
403b09
-                self._pipe.SetInformationTrustedDomain(trustdom_handle,
403b09
-                                                       lsa.LSA_TRUSTED_DOMAIN_INFO_INFO_EX, info)
403b09
+                self._pipe.SetInformationTrustedDomain(
403b09
+                                      trustdom_handle,
403b09
+                                      lsa.LSA_TRUSTED_DOMAIN_INFO_INFO_EX, info)
403b09
             except RuntimeError as e:
403b09
-                root_logger.error('unable to set trust transitivity status: %s' % (str(e)))
403b09
+                root_logger.error(
403b09
+                      'unable to set trust transitivity status: %s' % (str(e)))
403b09
 
403b09
         if self.info['is_pdc'] or trust_external:
403b09
             self.update_ftinfo(another_domain)
403b09
@@ -1119,12 +1213,13 @@ class TrustDomainInstance(object):
403b09
     def verify_trust(self, another_domain):
403b09
         def retrieve_netlogon_info_2(logon_server, domain, function_code, data):
403b09
             try:
403b09
-                netr_pipe = netlogon.netlogon(domain.binding, domain.parm, domain.creds)
403b09
-                result = netr_pipe.netr_LogonControl2Ex(logon_server=logon_server,
403b09
+                netr_pipe = netlogon.netlogon(domain.binding,
403b09
+                                              domain.parm, domain.creds)
403b09
+                result = netr_pipe.netr_LogonControl2Ex(
403b09
+                                           logon_server=logon_server,
403b09
                                            function_code=function_code,
403b09
                                            level=2,
403b09
-                                           data=data
403b09
-                                           )
403b09
+                                           data=data)
403b09
                 return result
403b09
             except RuntimeError as e:
403b09
                 num, message = e.args  # pylint: disable=unpacking-non-sequence
403b09
@@ -1135,9 +1230,11 @@ class TrustDomainInstance(object):
403b09
                                           another_domain.info['dns_domain'])
403b09
 
403b09
         if result and result.flags and netlogon.NETLOGON_VERIFY_STATUS_RETURNED:
403b09
-            if result.pdc_connection_status[0] != 0 and result.tc_connection_status[0] != 0:
403b09
+            if result.pdc_connection_status[0] != 0 and \
403b09
+               result.tc_connection_status[0] != 0:
403b09
                 if result.pdc_connection_status[1] == "WERR_ACCESS_DENIED":
403b09
-                    # Most likely AD DC hit another IPA replica which yet has no trust secret replicated
403b09
+                    # Most likely AD DC hit another IPA replica which
403b09
+                    # yet has no trust secret replicated
403b09
 
403b09
                     # Sleep and repeat again
403b09
                     self.validation_attempts += 1
403b09
@@ -1176,23 +1273,23 @@ class TrustDomainInstance(object):
403b09
 
403b09
 def fetch_domains(api, mydomain, trustdomain, creds=None, server=None):
403b09
     trust_flags = dict(
403b09
-                NETR_TRUST_FLAG_IN_FOREST = 0x00000001,
403b09
-                NETR_TRUST_FLAG_OUTBOUND  = 0x00000002,
403b09
-                NETR_TRUST_FLAG_TREEROOT  = 0x00000004,
403b09
-                NETR_TRUST_FLAG_PRIMARY   = 0x00000008,
403b09
-                NETR_TRUST_FLAG_NATIVE    = 0x00000010,
403b09
-                NETR_TRUST_FLAG_INBOUND   = 0x00000020,
403b09
-                NETR_TRUST_FLAG_MIT_KRB5  = 0x00000080,
403b09
-                NETR_TRUST_FLAG_AES       = 0x00000100)
403b09
+                NETR_TRUST_FLAG_IN_FOREST=0x00000001,
403b09
+                NETR_TRUST_FLAG_OUTBOUND=0x00000002,
403b09
+                NETR_TRUST_FLAG_TREEROOT=0x00000004,
403b09
+                NETR_TRUST_FLAG_PRIMARY=0x00000008,
403b09
+                NETR_TRUST_FLAG_NATIVE=0x00000010,
403b09
+                NETR_TRUST_FLAG_INBOUND=0x00000020,
403b09
+                NETR_TRUST_FLAG_MIT_KRB5=0x00000080,
403b09
+                NETR_TRUST_FLAG_AES=0x00000100)
403b09
 
403b09
     trust_attributes = dict(
403b09
-                NETR_TRUST_ATTRIBUTE_NON_TRANSITIVE     = 0x00000001,
403b09
-                NETR_TRUST_ATTRIBUTE_UPLEVEL_ONLY       = 0x00000002,
403b09
-                NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN = 0x00000004,
403b09
-                NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE  = 0x00000008,
403b09
-                NETR_TRUST_ATTRIBUTE_CROSS_ORGANIZATION = 0x00000010,
403b09
-                NETR_TRUST_ATTRIBUTE_WITHIN_FOREST      = 0x00000020,
403b09
-                NETR_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL  = 0x00000040)
403b09
+                NETR_TRUST_ATTRIBUTE_NON_TRANSITIVE=0x00000001,
403b09
+                NETR_TRUST_ATTRIBUTE_UPLEVEL_ONLY=0x00000002,
403b09
+                NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN=0x00000004,
403b09
+                NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE=0x00000008,
403b09
+                NETR_TRUST_ATTRIBUTE_CROSS_ORGANIZATION=0x00000010,
403b09
+                NETR_TRUST_ATTRIBUTE_WITHIN_FOREST=0x00000020,
403b09
+                NETR_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL=0x00000040)
403b09
 
403b09
     def communicate(td):
403b09
         td.init_lsa_pipe(td.info['dc'])
403b09
@@ -1314,7 +1411,8 @@ class TrustDomainJoins(object):
403b09
         ld.retrieve(installutils.get_fqdn())
403b09
         self.local_domain = ld
403b09
 
403b09
-    def populate_remote_domain(self, realm, realm_server=None, realm_admin=None, realm_passwd=None):
403b09
+    def populate_remote_domain(self, realm, realm_server=None,
403b09
+                               realm_admin=None, realm_passwd=None):
403b09
         def get_instance(self):
403b09
             # Fetch data from foreign domain using password only
403b09
             rd = TrustDomainInstance('')
403b09
@@ -1330,7 +1428,8 @@ class TrustDomainJoins(object):
403b09
         if realm_server is None:
403b09
             rd.retrieve_anonymously(realm, discover_srv=True, search_pdc=True)
403b09
         else:
403b09
-            rd.retrieve_anonymously(realm_server, discover_srv=False, search_pdc=True)
403b09
+            rd.retrieve_anonymously(realm_server,
403b09
+                                    discover_srv=False, search_pdc=True)
403b09
         rd.read_only = True
403b09
         if realm_admin and realm_passwd:
403b09
             if 'name' in rd.info:
403b09
@@ -1339,12 +1438,14 @@ class TrustDomainJoins(object):
403b09
                     # realm admin is in DOMAIN\user format
403b09
                     # strip DOMAIN part as we'll enforce the one discovered
403b09
                     realm_admin = names[-1]
403b09
-                auth_string = u"%s\%s%%%s" % (rd.info['name'], realm_admin, realm_passwd)
403b09
+                auth_string = u"%s\%s%%%s" \
403b09
+                              % (rd.info['name'], realm_admin, realm_passwd)
403b09
                 td = get_instance(self)
403b09
                 td.creds.parse_string(auth_string)
403b09
                 td.creds.set_workstation(self.local_domain.hostname)
403b09
                 if realm_server is None:
403b09
-                    # we must have rd.info['dns_hostname'] then, part of anonymous discovery
403b09
+                    # we must have rd.info['dns_hostname'] then
403b09
+                    # as it is part of the anonymous discovery
403b09
                     td.retrieve(rd.info['dns_hostname'])
403b09
                 else:
403b09
                     td.retrieve(realm_server)
403b09
@@ -1358,8 +1459,8 @@ class TrustDomainJoins(object):
403b09
         """
403b09
         Generate list of records for forest trust information about
403b09
         our realm domains. Note that the list generated currently
403b09
-        includes only top level domains, no exclusion domains, and no TDO objects
403b09
-        as we handle the latter in a separate way
403b09
+        includes only top level domains, no exclusion domains, and
403b09
+        no TDO objects as we handle the latter in a separate way
403b09
         """
403b09
         if self.local_domain.read_only:
403b09
             return
403b09
@@ -1367,10 +1468,15 @@ class TrustDomainJoins(object):
403b09
         self.local_domain.ftinfo_records = []
403b09
 
403b09
         realm_domains = self.api.Command.realmdomains_show()['result']
403b09
-        # Use realmdomains' modification timestamp to judge records last update time
403b09
-        entry = self.api.Backend.ldap2.get_entry(realm_domains['dn'], ['modifyTimestamp'])
403b09
+        # Use realmdomains' modification timestamp
403b09
+        # to judge records' last update time
403b09
+        entry = self.api.Backend.ldap2.get_entry(
403b09
+                    realm_domains['dn'], ['modifyTimestamp'])
403b09
         # Convert the timestamp to Windows 64-bit timestamp format
403b09
-        trust_timestamp = long(time.mktime(entry['modifytimestamp'][0].timetuple())*1e7+116444736000000000)
403b09
+        trust_timestamp = long(
403b09
+                time.mktime(
403b09
+                     entry.single_value.get('modifytimestamp').timetuple()
403b09
+                )*1e7+116444736000000000)
403b09
 
403b09
         for dom in realm_domains['associateddomain']:
403b09
             ftinfo = dict()
403b09
@@ -1379,7 +1485,8 @@ class TrustDomainJoins(object):
403b09
             ftinfo['rec_type'] = lsa.LSA_FOREST_TRUST_TOP_LEVEL_NAME
403b09
             self.local_domain.ftinfo_records.append(ftinfo)
403b09
 
403b09
-    def join_ad_full_credentials(self, realm, realm_server, realm_admin, realm_passwd, trust_type):
403b09
+    def join_ad_full_credentials(self, realm, realm_server, realm_admin,
403b09
+                                 realm_passwd, trust_type):
403b09
         if not self.configured:
403b09
             return None
403b09
 
403b09
@@ -1392,24 +1499,33 @@ class TrustDomainJoins(object):
403b09
             )
403b09
 
403b09
         trust_external = bool(self.__allow_behavior & TRUST_JOIN_EXTERNAL)
403b09
-        if self.remote_domain.info['dns_domain'] != self.remote_domain.info['dns_forest']:
403b09
+        if self.remote_domain.info['dns_domain'] != \
403b09
+           self.remote_domain.info['dns_forest']:
403b09
             if not trust_external:
403b09
-                raise errors.NotAForestRootError(forest=self.remote_domain.info['dns_forest'],
403b09
-                                                 domain=self.remote_domain.info['dns_domain'])
403b09
+                raise errors.NotAForestRootError(
403b09
+                          forest=self.remote_domain.info['dns_forest'],
403b09
+                          domain=self.remote_domain.info['dns_domain'])
403b09
 
403b09
         if not self.remote_domain.read_only:
403b09
             trustdom_pass = samba.generate_random_password(128, 128)
403b09
             self.get_realmdomains()
403b09
             self.remote_domain.establish_trust(self.local_domain,
403b09
-                                               trustdom_pass, trust_type, trust_external)
403b09
+                                               trustdom_pass,
403b09
+                                               trust_type, trust_external)
403b09
             self.local_domain.establish_trust(self.remote_domain,
403b09
-                                              trustdom_pass, trust_type, trust_external)
403b09
-            # if trust is inbound, we don't need to verify it because AD DC will respond
403b09
-            # with WERR_NO_SUCH_DOMAIN -- in only does verification for outbound trusts.
403b09
+                                              trustdom_pass,
403b09
+                                              trust_type, trust_external)
403b09
+            # if trust is inbound, we don't need to verify it because
403b09
+            # AD DC will respond with WERR_NO_SUCH_DOMAIN --
403b09
+            # it only does verification for outbound trusts.
403b09
             result = True
403b09
             if trust_type == TRUST_BIDIRECTIONAL:
403b09
                 result = self.remote_domain.verify_trust(self.local_domain)
403b09
-            return dict(local=self.local_domain, remote=self.remote_domain, verified=result)
403b09
+            return dict(
403b09
+                        local=self.local_domain,
403b09
+                        remote=self.remote_domain,
403b09
+                        verified=result
403b09
+                       )
403b09
         return None
403b09
 
403b09
     def join_ad_ipa_half(self, realm, realm_server, trustdom_passwd, trust_type):
403b09
@@ -1420,11 +1536,18 @@ class TrustDomainJoins(object):
403b09
             self.populate_remote_domain(realm, realm_server, realm_passwd=None)
403b09
 
403b09
         trust_external = bool(self.__allow_behavior & TRUST_JOIN_EXTERNAL)
403b09
-        if self.remote_domain.info['dns_domain'] != self.remote_domain.info['dns_forest']:
403b09
+        if self.remote_domain.info['dns_domain'] != \
403b09
+           self.remote_domain.info['dns_forest']:
403b09
             if not trust_external:
403b09
-                raise errors.NotAForestRootError(forest=self.remote_domain.info['dns_forest'],
403b09
-                                                 domain=self.remote_domain.info['dns_domain'])
403b09
+                raise errors.NotAForestRootError(
403b09
+                          forest=self.remote_domain.info['dns_forest'],
403b09
+                          domain=self.remote_domain.info['dns_domain'])
403b09
 
403b09
         self.local_domain.establish_trust(self.remote_domain,
403b09
-                                          trustdom_passwd, trust_type, trust_external)
403b09
-        return dict(local=self.local_domain, remote=self.remote_domain, verified=False)
403b09
+                                          trustdom_passwd,
403b09
+                                          trust_type, trust_external)
403b09
+        return dict(
403b09
+                    local=self.local_domain,
403b09
+                    remote=self.remote_domain,
403b09
+                    verified=False
403b09
+                   )
403b09
-- 
403b09
2.7.4
403b09