Skip to content

Commit 6e471e3

Browse files
committed
feat(ldapobject): Add wrapper for ldap_connect
1 parent e643924 commit 6e471e3

3 files changed

Lines changed: 63 additions & 0 deletions

File tree

Lib/ldap/ldapobject.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,13 @@ def fileno(self):
171171
"""
172172
return self.get_option(ldap.OPT_DESC)
173173

174+
def connect(self):
175+
"""
176+
connect() -> None
177+
Establishes LDAP connection if needed.
178+
"""
179+
return self._ldap_call(self._l.connect)
180+
174181
def abandon_ext(self,msgid,serverctrls=None,clientctrls=None):
175182
"""
176183
abandon_ext(msgid[,serverctrls=None[,clientctrls=None]]) -> None

Modules/LDAPObject.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,6 +1475,38 @@ l_ldap_extended_operation(LDAPObject *self, PyObject *args)
14751475
return PyLong_FromLong(msgid);
14761476
}
14771477

1478+
/* ldap_connect */
1479+
1480+
static PyObject *
1481+
l_ldap_connect(LDAPObject *self, PyObject Py_UNUSED(args))
1482+
{
1483+
#if LDAP_VENDOR_VERSION >= 20500
1484+
int ldaperror;
1485+
1486+
if (ldap_version_info.ldapai_vendor_version < 20500)
1487+
#endif
1488+
{
1489+
PyErr_SetString(PyExc_NotImplementedError,
1490+
"loaded libldap doesn't support this feature");
1491+
return NULL;
1492+
}
1493+
1494+
#if LDAP_VENDOR_VERSION >= 20500
1495+
if (not_valid(self))
1496+
return NULL;
1497+
1498+
LDAP_BEGIN_ALLOW_THREADS(self);
1499+
ldaperror = ldap_connect(self->ldap);
1500+
LDAP_END_ALLOW_THREADS(self);
1501+
1502+
if ( ldaperror != LDAP_SUCCESS )
1503+
return LDAPerror(self->ldap);
1504+
1505+
Py_INCREF(Py_None);
1506+
return Py_None;
1507+
#endif
1508+
}
1509+
14781510
/* methods */
14791511

14801512
static PyMethodDef methods[] = {
@@ -1504,6 +1536,7 @@ static PyMethodDef methods[] = {
15041536
{"cancel", (PyCFunction)l_ldap_cancel, METH_VARARGS},
15051537
#endif
15061538
{"extop", (PyCFunction)l_ldap_extended_operation, METH_VARARGS},
1539+
{"connect", (PyCFunction)l_ldap_connect, METH_NOARGS},
15071540
{NULL, NULL}
15081541
};
15091542

Tests/t_cext.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,29 @@ def test_simple_anonymous_bind(self):
280280
self.assertEqual(pmsg, [])
281281
self.assertEqual(ctrls, [])
282282

283+
@unittest.skipUnless(
284+
_ldap.VENDOR_VERSION >= 20500 and \
285+
_ldap._VENDOR_VERSION_RUNTIME >= 20500,
286+
reason="Test requires libldap 2.5+"
287+
)
288+
def test_connect(self):
289+
l = self._open_conn(bind=False)
290+
invalid_fileno = l.get_option(_ldap.OPT_DESC)
291+
l.connect()
292+
fileno = l.get_option(_ldap.OPT_DESC)
293+
self.assertNotEqual(invalid_fileno, fileno)
294+
295+
self._bind_conn(l)
296+
297+
@unittest.skipUnless(
298+
_ldap._VENDOR_VERSION_RUNTIME < 20500,
299+
reason="Test requires linking to libldap < 2.5"
300+
)
301+
def test_connect_notimpl(self):
302+
l = self._open_conn(bind=False)
303+
with self.assertRaises(NotImplementedError):
304+
l.connect()
305+
283306
def test_anon_rootdse_search(self):
284307
l = self._open_conn(bind=False)
285308
# see if we can get the rootdse with anon search (without prior bind)

0 commit comments

Comments
 (0)