From d0882d3edd6460913d27ebca22a4d3dde7e82e25 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Mon, 29 Jun 2020 13:41:51 +0200 Subject: [PATCH 1/5] Add words to spellchecker it looks like sphinxcontrib-spelling 5.1.2 does not like GPG and readthedocs. https://github.com/python-ldap/python-ldap/pull/361 Signed-off-by: Christian Heimes --- Doc/spelling_wordlist.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Doc/spelling_wordlist.txt b/Doc/spelling_wordlist.txt index d13c0791..fb4a9903 100644 --- a/Doc/spelling_wordlist.txt +++ b/Doc/spelling_wordlist.txt @@ -56,6 +56,7 @@ filterstr filterStr formatOID func +GPG Heimdal hostport hrefTarget @@ -105,6 +106,7 @@ processResultsCount Proxied py rdn +readthedocs reentrant refmodule refreshAndPersist From ffb4a606cb431efc57a21a4c7570a9c30886e542 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Sat, 20 Jun 2020 17:40:27 +0200 Subject: [PATCH 2/5] Fix macOS SDK builds without ldap_init_fd macOS system libldap 2.4.28 does not have ldap_init_fd symbol. Disable initialize_fd when Apple libldap 2.4.28 is detected. Also run some macOS tests on Travis CI. Since the SDK does not ship slapd, testing is rather limited. Fixes: https://github.com/python-ldap/python-ldap/issues/359 Signed-off-by: Christian Heimes --- .travis.yml | 9 +++++++++ Lib/ldap/constants.py | 1 + Lib/ldap/ldapobject.py | 2 ++ Lib/slapdtest/__init__.py | 1 + Lib/slapdtest/_slapdtest.py | 8 ++++++++ Modules/common.h | 5 +++++ Modules/constants_generated.h | 8 ++++++++ Modules/functions.c | 4 ++++ Tests/t_cext.py | 5 ++++- Tests/t_ldapobject.py | 2 ++ tox.ini | 20 ++++++++++++++++++++ 11 files changed, 64 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 22224cab..99829dc9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: python +group: travis_latest sudo: false @@ -14,6 +15,13 @@ addons: # Note: when updating Python versions, also change setup.py and tox.ini matrix: include: + - os: osx + osx_image: xcode11.4 + language: minimal + env: + - TOXENV=macos + - CFLAGS_warnings="-Wall -Werror=declaration-after-statement" + - CFLAGS_std="-std=c99" - python: 2.7 env: - TOXENV=py27 @@ -36,6 +44,7 @@ matrix: - python: 3.7 env: - TOXENV=py37 + - CFLAGS_std="-std=c99" - WITH_GCOV=1 dist: xenial sudo: true diff --git a/Lib/ldap/constants.py b/Lib/ldap/constants.py index 641d49ce..5e178a17 100644 --- a/Lib/ldap/constants.py +++ b/Lib/ldap/constants.py @@ -344,6 +344,7 @@ class Str(Constant): Feature('LIBLDAP_R', 'HAVE_LIBLDAP_R'), Feature('SASL_AVAIL', 'HAVE_SASL'), Feature('TLS_AVAIL', 'HAVE_TLS'), + Feature('INIT_FD_AVAIL', 'HAVE_LDAP_INIT_FD'), Str("CONTROL_MANAGEDSAIT"), Str("CONTROL_PROXY_AUTHZ"), diff --git a/Lib/ldap/ldapobject.py b/Lib/ldap/ldapobject.py index b44d90cd..3c9634ca 100644 --- a/Lib/ldap/ldapobject.py +++ b/Lib/ldap/ldapobject.py @@ -104,6 +104,8 @@ def __init__( self._uri = uri self._ldap_object_lock = self._ldap_lock('opcall') if fileno is not None: + if not hasattr(_ldap, "initialize_fd"): + raise ValueError("libldap does not support initialize_fd") if hasattr(fileno, "fileno"): fileno = fileno.fileno() self._l = ldap.functions._ldap_function_call( diff --git a/Lib/slapdtest/__init__.py b/Lib/slapdtest/__init__.py index 02ed317f..1371bef2 100644 --- a/Lib/slapdtest/__init__.py +++ b/Lib/slapdtest/__init__.py @@ -9,4 +9,5 @@ from slapdtest._slapdtest import SlapdObject, SlapdTestCase, SysLogHandler from slapdtest._slapdtest import requires_ldapi, requires_sasl, requires_tls +from slapdtest._slapdtest import requires_init_fd from slapdtest._slapdtest import skip_unless_ci diff --git a/Lib/slapdtest/_slapdtest.py b/Lib/slapdtest/_slapdtest.py index de4c3e53..afd5304d 100644 --- a/Lib/slapdtest/_slapdtest.py +++ b/Lib/slapdtest/_slapdtest.py @@ -109,6 +109,14 @@ def requires_ldapi(): else: return identity +def requires_init_fd(): + if not ldap.INIT_FD_AVAIL: + return skip_unless_ci( + "test needs ldap.INIT_FD", feature='INIT_FD') + else: + return identity + + def _add_sbin(path): """Add /sbin and related directories to a command search path""" directories = path.split(os.pathsep) diff --git a/Modules/common.h b/Modules/common.h index 1ce2eb83..886024f2 100644 --- a/Modules/common.h +++ b/Modules/common.h @@ -24,11 +24,16 @@ /* openldap.h with ldap_init_fd() was introduced in 2.4.48 * see https://bugs.openldap.org/show_bug.cgi?id=8671 */ +#define HAVE_LDAP_INIT_FD 1 #include +#elif (defined(__APPLE__) && (LDAP_VENDOR_VERSION == 20428)) +/* macOS system libldap 2.4.28 does not have ldap_init_fd symbol */ +#undef HAVE_LDAP_INIT_FD #else /* ldap_init_fd() has been around for a very long time * SSSD has been defining the function for a while, so it's probably OK. */ +#define HAVE_LDAP_INIT_FD 1 #define LDAP_PROTO_TCP 1 #define LDAP_PROTO_UDP 2 #define LDAP_PROTO_IPC 3 diff --git a/Modules/constants_generated.h b/Modules/constants_generated.h index 3231e635..4a4cdb3e 100644 --- a/Modules/constants_generated.h +++ b/Modules/constants_generated.h @@ -329,6 +329,14 @@ if (PyModule_AddIntConstant(m, "TLS_AVAIL", 0) != 0) return -1; #endif +#ifdef HAVE_LDAP_INIT_FD +if (PyModule_AddIntConstant(m, "INIT_FD_AVAIL", 1) != 0) + return -1; +#else +if (PyModule_AddIntConstant(m, "INIT_FD_AVAIL", 0) != 0) + return -1; +#endif + add_string(CONTROL_MANAGEDSAIT); add_string(CONTROL_PROXY_AUTHZ); add_string(CONTROL_SUBENTRIES); diff --git a/Modules/functions.c b/Modules/functions.c index ce4a924a..b811708f 100644 --- a/Modules/functions.c +++ b/Modules/functions.c @@ -30,6 +30,7 @@ l_ldap_initialize(PyObject *unused, PyObject *args) return (PyObject *)newLDAPObject(ld); } +#ifdef HAVE_LDAP_INIT_FD /* initialize_fd(fileno, url) */ static PyObject * @@ -82,6 +83,7 @@ l_ldap_initialize_fd(PyObject *unused, PyObject *args) return (PyObject *)newLDAPObject(ld); } +#endif /* ldap_str2dn */ @@ -190,7 +192,9 @@ l_ldap_get_option(PyObject *self, PyObject *args) static PyMethodDef methods[] = { {"initialize", (PyCFunction)l_ldap_initialize, METH_VARARGS}, +#ifdef HAVE_LDAP_INIT_FD {"initialize_fd", (PyCFunction)l_ldap_initialize_fd, METH_VARARGS}, +#endif {"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}, diff --git a/Tests/t_cext.py b/Tests/t_cext.py index a19d3c33..1e27588b 100644 --- a/Tests/t_cext.py +++ b/Tests/t_cext.py @@ -18,7 +18,7 @@ # import the plain C wrapper module import _ldap -from slapdtest import SlapdTestCase, requires_tls +from slapdtest import SlapdTestCase, requires_tls, requires_init_fd class TestLdapCExtension(SlapdTestCase): @@ -251,12 +251,14 @@ def test_simple_bind_fileno(self): with self._open_conn_fd() as (sock, l): self.assertEqual(l.whoami_s(), "dn:" + self.server.root_dn) + @requires_init_fd() def test_simple_bind_fileno_invalid(self): with open(os.devnull) as f: l = _ldap.initialize_fd(f.fileno(), self.server.ldap_uri) with self.assertRaises(_ldap.SERVER_DOWN): self._bind_conn(l) + @requires_init_fd() def test_simple_bind_fileno_closed(self): with self._open_conn_fd() as (sock, l): self.assertEqual(l.whoami_s(), "dn:" + self.server.root_dn) @@ -264,6 +266,7 @@ def test_simple_bind_fileno_closed(self): with self.assertRaises(_ldap.SERVER_DOWN): l.whoami_s() + @requires_init_fd() def test_simple_bind_fileno_rebind(self): with self._open_conn_fd() as (sock, l): self.assertEqual(l.whoami_s(), "dn:" + self.server.root_dn) diff --git a/Tests/t_ldapobject.py b/Tests/t_ldapobject.py index 459ba768..6f1f2d24 100644 --- a/Tests/t_ldapobject.py +++ b/Tests/t_ldapobject.py @@ -33,6 +33,7 @@ from slapdtest import SlapdTestCase from slapdtest import requires_ldapi, requires_sasl, requires_tls +from slapdtest import requires_init_fd LDIF_TEMPLATE = """dn: %(suffix)s @@ -811,6 +812,7 @@ def test105_reconnect_restore(self): self.assertEqual(l1.whoami_s(), 'dn:'+bind_dn) +@requires_init_fd() class Test03_SimpleLDAPObjectWithFileno(Test00_SimpleLDAPObject): def _get_bytes_ldapobject(self, explicit=True, **kwargs): raise unittest.SkipTest("Test opens two sockets") diff --git a/tox.ini b/tox.ini index 81a38bf5..f7bc6c8a 100644 --- a/tox.ini +++ b/tox.ini @@ -73,6 +73,26 @@ basepython = pypy3.5 deps = {[testenv:pypy]deps} commands = {[testenv:pypy]commands} +[testenv:macos] +# Travis CI macOS image does not have slapd +# SDK libldap does not support ldap_init_fd +basepython = python3 +deps = {[testenv]deps} +passenv = {[testenv]passenv} +setenv = + CI_DISABLED=INIT_FD +commands = + {envpython} -m unittest -v \ + Tests/t_cidict.py \ + Tests/t_ldap_dn.py \ + Tests/t_ldap_filter.py \ + Tests/t_ldap_functions.py \ + Tests/t_ldap_modlist.py \ + Tests/t_ldap_schema_tokenizer.py \ + Tests/t_ldapurl.py \ + Tests/t_ldif.py \ + Tests/t_untested_mods.py + [testenv:doc] basepython = python3 deps = From bb4bc33ccd45b33f2b934785ea77bc966c109456 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Tue, 23 Jun 2020 11:06:34 +0200 Subject: [PATCH 3/5] Mention macOS issue in doc --- Doc/reference/ldap.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Doc/reference/ldap.rst b/Doc/reference/ldap.rst index a6d69287..8ca3e2a8 100644 --- a/Doc/reference/ldap.rst +++ b/Doc/reference/ldap.rst @@ -49,6 +49,8 @@ This module defines the following functions: and explicitly closed after the :class:`~ldap.ldapobject.LDAPObject` is unbound. The internal connection type is determined from the URI, ``TCP`` for ``ldap://`` / ``ldaps://``, ``IPC`` (``AF_UNIX``) for ``ldapi://``. + The is not available on macOS when python-ldap is compiled with system + libldap, see :py:const:`INIT_FD_AVAIL`. Note that internally the OpenLDAP function `ldap_initialize(3) `_ @@ -135,6 +137,12 @@ General Integer where a non-zero value indicates that python-ldap was built with support for SSL/TLS (OpenSSL or similar libs). +.. py:data:: INIT_FD_AVAIL + + Integer where a non-zero value indicates that python-ldap supports + :py:func:`initialize` from a file descriptor. The feature is generally + available except on macOS when python-ldap is compiled with system libldap. + .. _ldap-options: From 69360a63d1064c89d67b76151c4e47e53460d746 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 29 Jun 2020 15:37:35 +0200 Subject: [PATCH 4/5] Doc/reference/ldap.rst: Add missing word --- Doc/reference/ldap.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/reference/ldap.rst b/Doc/reference/ldap.rst index 8ca3e2a8..747502f9 100644 --- a/Doc/reference/ldap.rst +++ b/Doc/reference/ldap.rst @@ -49,7 +49,7 @@ This module defines the following functions: and explicitly closed after the :class:`~ldap.ldapobject.LDAPObject` is unbound. The internal connection type is determined from the URI, ``TCP`` for ``ldap://`` / ``ldaps://``, ``IPC`` (``AF_UNIX``) for ``ldapi://``. - The is not available on macOS when python-ldap is compiled with system + The parameter is not available on macOS when python-ldap is compiled with system libldap, see :py:const:`INIT_FD_AVAIL`. Note that internally the OpenLDAP function From dae0c5193d02709df6f6918d0e495180a1bff0c8 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 29 Jun 2020 16:43:42 +0200 Subject: [PATCH 5/5] Prepare release 3.3.1 (#365) --- CHANGES | 9 +++++++++ Lib/ldap/pkginfo.py | 2 +- Lib/ldapurl.py | 2 +- Lib/ldif.py | 2 +- Lib/slapdtest/__init__.py | 2 +- 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 711b665e..e129fffa 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,12 @@ +Released 3.3.1 2020-06-29 + +Changes: +* On MacOS, remove option to make LDAP connections from a file descriptor + when built wit the system libldap (which lacks the underlying function, + ``ldap_init_fd``) + + +---------------------------------------------------------------- Released 3.3.0 2020-06-18 Highlights: diff --git a/Lib/ldap/pkginfo.py b/Lib/ldap/pkginfo.py index d99d2d00..dd7b3a84 100644 --- a/Lib/ldap/pkginfo.py +++ b/Lib/ldap/pkginfo.py @@ -2,6 +2,6 @@ """ meta attributes for packaging which does not import any dependencies """ -__version__ = '3.3.0' +__version__ = '3.3.1' __author__ = u'python-ldap project' __license__ = 'Python style' diff --git a/Lib/ldapurl.py b/Lib/ldapurl.py index 7a0017c6..513c08da 100644 --- a/Lib/ldapurl.py +++ b/Lib/ldapurl.py @@ -4,7 +4,7 @@ See https://www.python-ldap.org/ for details. """ -__version__ = '3.3.0' +__version__ = '3.3.1' __all__ = [ # constants diff --git a/Lib/ldif.py b/Lib/ldif.py index f07f42dd..cde1dd5c 100644 --- a/Lib/ldif.py +++ b/Lib/ldif.py @@ -6,7 +6,7 @@ from __future__ import unicode_literals -__version__ = '3.3.0' +__version__ = '3.3.1' __all__ = [ # constants diff --git a/Lib/slapdtest/__init__.py b/Lib/slapdtest/__init__.py index 1371bef2..c56f8c35 100644 --- a/Lib/slapdtest/__init__.py +++ b/Lib/slapdtest/__init__.py @@ -5,7 +5,7 @@ See https://www.python-ldap.org/ for details. """ -__version__ = '3.3.0' +__version__ = '3.3.1' from slapdtest._slapdtest import SlapdObject, SlapdTestCase, SysLogHandler from slapdtest._slapdtest import requires_ldapi, requires_sasl, requires_tls