[python-ldap] ldap.init_fd() patch for python-ldap-2.4.15
Mark R Bannister
mark at proseconsulting.co.uk
Tue Sep 2 00:25:22 CEST 2014
Hi,
I needed ldap.init_fd(), so I wrote a patch. Please find attached. Hope
this works for you too. I've only tested on OpenSuSE.
This is an example of how to use it:
###
import ldap
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("localhost", 389))
l = ldap.init_fd(sock.fileno(), ldap.PROTO_TCP, "ldap://localhost:389")
...
###
I found I had to install openldap2-debugsource to get ldap_pvt.h. I
added /usr/src/debug/openldap-2.4.33/include to include_dirs in
setup.cfg to get it to compile. This header worked fine with
openldap2-2.4.26.
Best regards,
Mark R. Bannister.
Author of DBIS:
http://technicalprose.blogspot.co.uk/2013/08/introducing-dbis.html
-------------- next part --------------
diff -u -r a/python-ldap-2.4.15/Lib/ldap/functions.py b/python-ldap-2.4.15/Lib/ldap/functions.py
--- a/python-ldap-2.4.15/Lib/ldap/functions.py 2011-11-25 12:22:02.000000000 +0000
+++ b/python-ldap-2.4.15/Lib/ldap/functions.py 2014-09-01 22:34:16.881369666 +0100
@@ -21,7 +21,7 @@
from ldap import __version__
__all__ = [
- 'open','initialize','init',
+ 'open','initialize','init_fd','init',
'explode_dn','explode_rdn',
'get_option','set_option',
]
@@ -32,7 +32,7 @@
from ldap.dn import explode_dn,explode_rdn
-from ldap.ldapobject import LDAPObject
+from ldap.ldapobject import LDAPObject,LDAPObjectFromFD
if __debug__:
# Tracing is only supported in debugging mode
@@ -91,6 +91,29 @@
return LDAPObject(uri,trace_level,trace_file,trace_stack_limit)
+def init_fd(fd,proto,uri=None,trace_level=0,trace_file=sys.stdout,trace_stack_limit=None):
+ """
+ Return LDAPObject instance by opening LDAP connection over
+ existing connection on the provided socket
+
+ Parameters:
+ fd
+ File descriptor of an already-opened socket, e.g. socket.fileno()
+ proto
+ One of ldap.PROTO_TCP, ldap.PROTO_UDP or ldap.PROTO_IPC.
+ uri
+ LDAP URL containing at least connection scheme and hostport,
+ e.g. ldap://localhost:389
+ This is optional and is provided for informational purposes.
+ trace_level
+ If non-zero a trace output of LDAP calls is generated.
+ trace_file
+ File object where to write the trace output to.
+ Default is to use stdout.
+ """
+ return LDAPObjectFromFD(fd,proto,uri,trace_level,trace_file,trace_stack_limit)
+
+
def open(host,port=389,trace_level=0,trace_file=sys.stdout,trace_stack_limit=None):
"""
Return LDAPObject instance by opening LDAP connection to
diff -u -r a/python-ldap-2.4.15/Lib/ldap/__init__.py b/python-ldap-2.4.15/Lib/ldap/__init__.py
--- a/python-ldap-2.4.15/Lib/ldap/__init__.py 2014-03-24 10:20:16.000000000 +0000
+++ b/python-ldap-2.4.15/Lib/ldap/__init__.py 2014-09-01 21:38:40.930387447 +0100
@@ -82,7 +82,7 @@
# Create module-wide lock for serializing all calls into underlying LDAP lib
_ldap_module_lock = LDAPLock(desc='Module wide')
-from functions import open,initialize,init,get_option,set_option
+from functions import open,initialize,init_fd,init,get_option,set_option
from ldap.dn import explode_dn,explode_rdn,str2dn,dn2str
del str2dn
diff -u -r a/python-ldap-2.4.15/Lib/ldap/ldapobject.py b/python-ldap-2.4.15/Lib/ldap/ldapobject.py
--- a/python-ldap-2.4.15/Lib/ldap/ldapobject.py 2014-03-07 20:01:12.000000000 +0000
+++ b/python-ldap-2.4.15/Lib/ldap/ldapobject.py 2014-09-01 22:58:01.736461427 +0100
@@ -23,6 +23,8 @@
__all__ = [
'LDAPObject',
'SimpleLDAPObject',
+ 'LDAPObjectFromFD',
+ 'SimpleLDAPObjectFromFD',
'NonblockingLDAPObject',
'ReconnectLDAPObject',
]
@@ -879,6 +881,28 @@
return self._apply_method_s(SimpleLDAPObject.whoami_s,*args,**kwargs)
+class SimpleLDAPObjectFromFD(SimpleLDAPObject):
+ """
+ Identical to SimpleLDAPObject except that it uses ldap_init_fd()
+ """
+
+ def __init__(
+ self,fd,proto,uri=None,
+ trace_level=0,trace_file=None,trace_stack_limit=5
+ ):
+ self._trace_level = trace_level
+ self._trace_file = trace_file or sys.stdout
+ self._trace_stack_limit = trace_stack_limit
+ self._fd = fd
+ self._proto = proto
+ self._uri = uri
+ self._ldap_object_lock = self._ldap_lock('opcall')
+ self._l = ldap.functions._ldap_function_call(ldap._ldap_module_lock,_ldap.init_fd,fd,proto,uri)
+ self.timeout = -1
+ self.protocol_version = ldap.VERSION3
+
+
# The class called LDAPObject will be used as default for
# ldap.open() and ldap.initialize()
LDAPObject = SimpleLDAPObject
+LDAPObjectFromFD = SimpleLDAPObjectFromFD
diff -u -r a/python-ldap-2.4.15/Modules/constants.c b/python-ldap-2.4.15/Modules/constants.c
--- a/python-ldap-2.4.15/Modules/constants.c 2014-03-24 10:20:16.000000000 +0000
+++ b/python-ldap-2.4.15/Modules/constants.c 2014-09-01 22:24:39.152943357 +0100
@@ -6,6 +6,7 @@
#include "constants.h"
#include "lber.h"
#include "ldap.h"
+#include "ldap_pvt.h"
static PyObject* reverse;
static PyObject* forward;
@@ -140,6 +141,10 @@
add_int(d,DEREF_ALWAYS);
add_int(d,NO_LIMIT);
+ add_int(d,PROTO_TCP);
+ add_int(d,PROTO_UDP);
+ add_int(d,PROTO_IPC);
+
add_int(d,OPT_API_INFO);
add_int(d,OPT_DEREF);
add_int(d,OPT_SIZELIMIT);
diff -u -r a/python-ldap-2.4.15/Modules/functions.c b/python-ldap-2.4.15/Modules/functions.c
--- a/python-ldap-2.4.15/Modules/functions.c 2011-06-08 20:35:33.000000000 +0100
+++ b/python-ldap-2.4.15/Modules/functions.c 2014-09-01 22:43:23.434833804 +0100
@@ -7,6 +7,7 @@
#include "berval.h"
#include "errors.h"
#include "options.h"
+#include "ldap_pvt.h"
/* ldap_initialize */
@@ -29,6 +30,27 @@
}
+/* ldap_init_fd */
+
+static PyObject*
+l_ldap_init_fd(PyObject* unused, PyObject *args)
+{
+ char *uri = NULL;
+ LDAP *ld = NULL;
+ int ret, fd, proto;
+
+ if (!PyArg_ParseTuple(args, "ii|s", &fd, &proto, &uri))
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ ret = ldap_init_fd((ber_socket_t)fd, proto, uri, &ld);
+ Py_END_ALLOW_THREADS
+ if (ret != LDAP_SUCCESS)
+ return LDAPerror(ld, "ldap_init_fd");
+ return (PyObject*)newLDAPObject(ld);
+}
+
+
/* ldap_str2dn */
static PyObject*
@@ -137,6 +159,7 @@
static PyMethodDef methods[] = {
{ "initialize", (PyCFunction)l_ldap_initialize, METH_VARARGS },
+ { "init_fd", (PyCFunction)l_ldap_init_fd, METH_VARARGS },
{ "str2dn", (PyCFunction)l_ldap_str2dn, METH_VARARGS },
{ "set_option", (PyCFunction)l_ldap_set_option, METH_VARARGS },
{ "get_option", (PyCFunction)l_ldap_get_option, METH_VARARGS },
More information about the python-ldap
mailing list