On 7.3.2013 17:59, Petr Viktorin wrote:
On 03/07/2013 04:33 PM, Jan Cholasta wrote:
On 7.3.2013 14:53, Petr Viktorin wrote:
On 03/07/2013 01:43 PM, Jan Cholasta wrote:
Hi,

these patches add flags to LDAPClient and IPAdmin constructors which
can
be used to disable schema retrieval and decoding of attributes. This
should make interacting with AD easier (see
<http://www.redhat.com/archives/freeipa-devel/2013-March/msg00076.html>).



Honza
[...]

Updated patches attached.

Honza


In LDAPEntry.__setitem__, schema.get_obj is used without checking if the
schema is None.


I knew I forgot something! Thanks. Fixed.

Updated patches attached.

Honza

--
Jan Cholasta
>From 411ba6d422b39e27deab63acfc127573e7db1fb2 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Thu, 7 Mar 2013 10:50:57 +0100
Subject: [PATCH 1/4] Do not fail if schema cannot be retrieved from LDAP
 server.

---
 ipaserver/ipaldap.py | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/ipaserver/ipaldap.py b/ipaserver/ipaldap.py
index 4a46532..d9f91d5 100644
--- a/ipaserver/ipaldap.py
+++ b/ipaserver/ipaldap.py
@@ -270,13 +270,19 @@ class IPASimpleLDAPObject(object):
         self.log = log_mgr.get_logger(self)
         self.uri = uri
         self.conn = SimpleLDAPObject(uri)
+        self._has_schema = False
         self._schema = None
         self._force_schema_updates = force_schema_updates
 
     def _get_schema(self):
-        if self._schema is None:
-            self._schema = schema_cache.get_schema(
-                self.uri, self.conn, force_update=self._force_schema_updates)
+        if not self._has_schema:
+            try:
+                self._schema = schema_cache.get_schema(
+                    self.uri, self.conn,
+                    force_update=self._force_schema_updates)
+            except (errors.ExecutionError, IndexError):
+                pass
+            self._has_schema = True
         return self._schema
 
     schema = property(_get_schema, None, None, 'schema associated with this LDAP server')
@@ -307,6 +313,7 @@ class IPASimpleLDAPObject(object):
         # logical operations that have the potential to cause a schema
         # change.
 
+        self._has_schema = False
         self._schema = None
 
     def get_syntax(self, attr):
@@ -315,6 +322,9 @@ class IPASimpleLDAPObject(object):
         if syntax is not None:
             return syntax
 
+        if self.schema is None:
+            return None
+
         # Try to lookup the syntax in the schema returned by the server
         obj = self.schema.get_obj(ldap.schema.AttributeType, attr)
         if obj is not None:
@@ -708,12 +718,8 @@ class LDAPEntry(dict):
         else:
             self._names[name] = name
 
-            try:
-                schema = self._conn.schema
-            except:
-                pass
-            else:
-                attrtype = schema.get_obj(ldap.schema.AttributeType,
+            if self._conn.schema is not None:
+                attrtype = self._conn.schema.get_obj(ldap.schema.AttributeType,
                     name.encode('utf-8'))
                 if attrtype is not None:
                     for altname in attrtype.names:
-- 
1.8.1

>From f6c25d9d8abe318745ddb5726a14f4aa9956b63a Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Thu, 7 Mar 2013 10:52:57 +0100
Subject: [PATCH 2/4] Allow disabling LDAP schema retrieval in LDAPClient and
 IPAdmin.

---
 ipaserver/ipaldap.py | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/ipaserver/ipaldap.py b/ipaserver/ipaldap.py
index d9f91d5..c814f57 100644
--- a/ipaserver/ipaldap.py
+++ b/ipaserver/ipaldap.py
@@ -255,7 +255,7 @@ class IPASimpleLDAPObject(object):
         'originscope':     DN_SYNTAX_OID, # DN
     })
 
-    def __init__(self, uri, force_schema_updates):
+    def __init__(self, uri, force_schema_updates, no_schema=False):
         """An internal LDAP connection object
 
         :param uri: The LDAP URI to connect to
@@ -266,15 +266,19 @@ class IPASimpleLDAPObject(object):
             Generally, it should be true if the API context is 'installer' or
             'updates', but it must be given explicitly since the API object
             is not always available
+        :param no_schema: If true, schema is never requested from the server.
         """
         self.log = log_mgr.get_logger(self)
         self.uri = uri
         self.conn = SimpleLDAPObject(uri)
+        self._no_schema = no_schema
         self._has_schema = False
         self._schema = None
         self._force_schema_updates = force_schema_updates
 
     def _get_schema(self):
+        if self._no_schema:
+            return None
         if not self._has_schema:
             try:
                 self._schema = schema_cache.get_schema(
@@ -1645,7 +1649,7 @@ class IPAdmin(LDAPClient):
 
     def __init__(self, host='', port=389, cacert=None, debug=None, ldapi=False,
                  realm=None, protocol=None, force_schema_updates=True,
-                 start_tls=False, ldap_uri=None):
+                 start_tls=False, ldap_uri=None, no_schema=False):
         self.conn = None
         log_mgr.get_logger(self, True)
         if debug and debug.lower() == "on":
@@ -1665,7 +1669,8 @@ class IPAdmin(LDAPClient):
 
         LDAPClient.__init__(self, ldap_uri)
 
-        self.conn = IPASimpleLDAPObject(ldap_uri, force_schema_updates=True)
+        self.conn = IPASimpleLDAPObject(ldap_uri, force_schema_updates=True,
+                                        no_schema=no_schema)
 
         if start_tls:
             self.conn.start_tls_s()
-- 
1.8.1

>From 052b54684346b3eaf6eafb6fdd0f35a91c29a910 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Thu, 7 Mar 2013 10:56:03 +0100
Subject: [PATCH 3/4] Allow disabling attribute decoding in LDAPClient and
 IPAdmin.

---
 ipaserver/ipaldap.py | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/ipaserver/ipaldap.py b/ipaserver/ipaldap.py
index c814f57..88c6fcc 100644
--- a/ipaserver/ipaldap.py
+++ b/ipaserver/ipaldap.py
@@ -255,7 +255,8 @@ class IPASimpleLDAPObject(object):
         'originscope':     DN_SYNTAX_OID, # DN
     })
 
-    def __init__(self, uri, force_schema_updates, no_schema=False):
+    def __init__(self, uri, force_schema_updates, no_schema=False,
+                 decode_attrs=True):
         """An internal LDAP connection object
 
         :param uri: The LDAP URI to connect to
@@ -267,6 +268,9 @@ class IPASimpleLDAPObject(object):
             'updates', but it must be given explicitly since the API object
             is not always available
         :param no_schema: If true, schema is never requested from the server.
+        :param decode_attrs:
+            If true, attributes are decoded to Python types according to their
+            syntax.
         """
         self.log = log_mgr.get_logger(self)
         self.uri = uri
@@ -275,6 +279,7 @@ class IPASimpleLDAPObject(object):
         self._has_schema = False
         self._schema = None
         self._force_schema_updates = force_schema_updates
+        self._decode_attrs = decode_attrs
 
     def _get_schema(self):
         if self._no_schema:
@@ -377,6 +382,9 @@ class IPASimpleLDAPObject(object):
         '''
         '''
 
+        if not self._decode_attrs:
+            return values
+
         ipa_values = []
 
         for original_value in values:
@@ -1649,7 +1657,8 @@ class IPAdmin(LDAPClient):
 
     def __init__(self, host='', port=389, cacert=None, debug=None, ldapi=False,
                  realm=None, protocol=None, force_schema_updates=True,
-                 start_tls=False, ldap_uri=None, no_schema=False):
+                 start_tls=False, ldap_uri=None, no_schema=False,
+                 decode_attrs=True):
         self.conn = None
         log_mgr.get_logger(self, True)
         if debug and debug.lower() == "on":
@@ -1670,7 +1679,8 @@ class IPAdmin(LDAPClient):
         LDAPClient.__init__(self, ldap_uri)
 
         self.conn = IPASimpleLDAPObject(ldap_uri, force_schema_updates=True,
-                                        no_schema=no_schema)
+                                        no_schema=no_schema,
+                                        decode_attrs=decode_attrs)
 
         if start_tls:
             self.conn.start_tls_s()
-- 
1.8.1

>From 4f3fad03972380fbb6b0c83c5b9e788f660accb8 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Thu, 7 Mar 2013 10:56:49 +0100
Subject: [PATCH 4/4] Disable schema retrieval and attribute decoding when
 talking to AD GC.

---
 ipaserver/dcerpc.py | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
index 4e85dc7..b8f83e9 100644
--- a/ipaserver/dcerpc.py
+++ b/ipaserver/dcerpc.py
@@ -434,7 +434,7 @@ class DomainValidator(object):
         Actual search in AD LDAP server, using SASL GSSAPI authentication
         Returns LDAP result or None
         """
-        conn = IPAdmin(host=host, port=port)
+        conn = IPAdmin(host=host, port=port, no_schema=True, decode_attrs=False)
         auth = self.__extract_trusted_auth(info)
         if attrs is None:
             attrs = []
@@ -450,10 +450,7 @@ class DomainValidator(object):
                 if basedn is None:
                     # Use domain root base DN
                     basedn = DN(*map(lambda p: ('dc', p), info['dns_domain'].split('.')))
-                # We don't use conn.getEntry() because it will attempt to fetch schema from GC and that will fail
-                filterstr = conn.encode(filter)
-                attrlist = conn.encode(attrs)
-                entries = conn.conn.conn.search_s(str(basedn), scope, filterstr, attrlist, 0)
+                entries = conn.get_entries(basedn, scope, filter, attrs)
                 os.environ["KRB5CCNAME"] = old_ccache
                 return entries
 
-- 
1.8.1

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to