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

The first three patches look good, except a nitpick below.


In the last patch, I don't see why you added back search_s. Is
get_entries inadequate in some way?

Nope, it's just that __search_in_gc uses it. Fixed.




From 33142d7e0a8508a783e1a1b4a7a22525337ce54d 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 | 16 +++++++++++++---
  1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/ipaserver/ipaldap.py b/ipaserver/ipaldap.py
[...]
+            try:
+                self._schema = schema_cache.get_schema(
+                    self.uri, self.conn,
+                    force_update=self._force_schema_updates)
+            except:

Don't use bare except.

Fixed.

Updated patches attached.

Honza

--
Jan Cholasta
>From 598dc757e1cb65499a2e46f2be6a09f65a9d6d7f 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 | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/ipaserver/ipaldap.py b/ipaserver/ipaldap.py
index 4a46532..2928a67 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:
-- 
1.8.1

>From 798abe2b369656f4ce99ea9f47a5c84fbe98775d 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 2928a67..0f153a5 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(
@@ -1649,7 +1653,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":
@@ -1669,7 +1673,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 bf5ddd4acb8184b125cc2c7cacdc48c0bec63a57 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 0f153a5..dfe696a 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:
@@ -1653,7 +1661,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":
@@ -1674,7 +1683,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 020287df63ffebb2802cd4a6d7838d0223e1870e 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