From 8d95115e758ac66fcbfe48a5922c7ab43d8d6820 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Mon, 28 Jun 2021 13:04:42 +0200 Subject: [PATCH] Fix SASL get/set options on big endian platforms Resolves: rhbz#1976827 --- ...-set-options-on-big-endian-platforms.patch | 169 ++++++++++++++++++ python-ldap.spec | 10 +- 2 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 0001-Fix-SASL-get-set-options-on-big-endian-platforms.patch diff --git a/0001-Fix-SASL-get-set-options-on-big-endian-platforms.patch b/0001-Fix-SASL-get-set-options-on-big-endian-platforms.patch new file mode 100644 index 0000000..a3f215f --- /dev/null +++ b/0001-Fix-SASL-get-set-options-on-big-endian-platforms.patch @@ -0,0 +1,169 @@ +From 30fb0a8bda8fbedc22de87b21b8b1b64de310a6b Mon Sep 17 00:00:00 2001 +From: Christian Heimes +Date: Mon, 28 Jun 2021 11:03:02 +0200 +Subject: [PATCH] Fix SASL get/set options on big endian platforms + +The options OPT_X_SASL_SSF_MIN, OPT_X_SASL_SSF_MAX, and OPT_X_SASL_SSF +take *ber_len_t as input and output arguments. ber_len_t is defined as +unsigned long: + +``` + /* LBER lengths (32 bits or larger) */ + #define LBER_LEN_T long + + typedef unsigned LBER_LEN_T ber_len_t; +``` + +Wrong type handling is causing issues on big endian platforms. + +Signed-off-by: Christian Heimes +--- + Modules/options.c | 41 ++++++++++++++++++++++++++++++----------- + Tests/t_ldapobject.py | 23 ++++++++++++++++++++++- + 2 files changed, 52 insertions(+), 12 deletions(-) + +diff --git a/Modules/options.c b/Modules/options.c +index 549a672..67511e8 100644 +--- a/Modules/options.c ++++ b/Modules/options.c +@@ -43,6 +43,10 @@ LDAP_set_option(LDAPObject *self, int option, PyObject *value) + double doubleval; + char *strval; + struct timeval tv; ++#if HAVE_SASL ++ /* unsigned long */ ++ ber_len_t blen; ++#endif + void *ptr; + LDAP *ld; + LDAPControl **controls = NULL; +@@ -89,10 +93,6 @@ LDAP_set_option(LDAPObject *self, int option, PyObject *value) + case LDAP_OPT_X_TLS_PROTOCOL_MIN: + #endif + #endif +-#ifdef HAVE_SASL +- case LDAP_OPT_X_SASL_SSF_MIN: +- case LDAP_OPT_X_SASL_SSF_MAX: +-#endif + #ifdef LDAP_OPT_X_KEEPALIVE_IDLE + case LDAP_OPT_X_KEEPALIVE_IDLE: + #endif +@@ -108,6 +108,16 @@ LDAP_set_option(LDAPObject *self, int option, PyObject *value) + return 0; + ptr = &intval; + break; ++ ++#ifdef HAVE_SASL ++ case LDAP_OPT_X_SASL_SSF_MIN: ++ case LDAP_OPT_X_SASL_SSF_MAX: ++ if (!PyArg_Parse(value, "k:set_option", &blen)) ++ return 0; ++ ptr = &blen; ++ break; ++#endif ++ + case LDAP_OPT_HOST_NAME: + case LDAP_OPT_URI: + #ifdef LDAP_OPT_DEFBASE +@@ -135,6 +145,7 @@ LDAP_set_option(LDAPObject *self, int option, PyObject *value) + return 0; + ptr = strval; + break; ++ + case LDAP_OPT_TIMEOUT: + case LDAP_OPT_NETWORK_TIMEOUT: + /* Float valued timeval options */ +@@ -239,6 +250,10 @@ LDAP_get_option(LDAPObject *self, int option) + LDAPAPIInfo apiinfo; + LDAPControl **lcs; + char *strval; ++#if HAVE_SASL ++ /* unsigned long */ ++ ber_len_t blen; ++#endif + PyObject *extensions, *v; + Py_ssize_t i, num_extensions; + +@@ -277,9 +292,6 @@ LDAP_get_option(LDAPObject *self, int option) + + return v; + +-#ifdef HAVE_SASL +- case LDAP_OPT_X_SASL_SSF: +-#endif + case LDAP_OPT_REFERRALS: + case LDAP_OPT_RESTART: + case LDAP_OPT_DEREF: +@@ -299,10 +311,6 @@ LDAP_get_option(LDAPObject *self, int option) + case LDAP_OPT_X_TLS_PROTOCOL_MIN: + #endif + #endif +-#ifdef HAVE_SASL +- case LDAP_OPT_X_SASL_SSF_MIN: +- case LDAP_OPT_X_SASL_SSF_MAX: +-#endif + #ifdef LDAP_OPT_X_SASL_NOCANON + case LDAP_OPT_X_SASL_NOCANON: + #endif +@@ -324,6 +332,17 @@ LDAP_get_option(LDAPObject *self, int option) + return option_error(res, "ldap_get_option"); + return PyInt_FromLong(intval); + ++#ifdef HAVE_SASL ++ case LDAP_OPT_X_SASL_SSF: ++ case LDAP_OPT_X_SASL_SSF_MIN: ++ case LDAP_OPT_X_SASL_SSF_MAX: ++#endif ++ /* ber_len_t options (unsigned long)*/ ++ res = LDAP_int_get_option(self, option, &blen); ++ if (res != LDAP_OPT_SUCCESS) ++ return option_error(res, "ldap_get_option"); ++ return PyLong_FromUnsignedLong(blen); ++ + case LDAP_OPT_HOST_NAME: + case LDAP_OPT_URI: + #ifdef LDAP_OPT_DEFBASE +diff --git a/Tests/t_ldapobject.py b/Tests/t_ldapobject.py +index e54bbfd..0a089c9 100644 +--- a/Tests/t_ldapobject.py ++++ b/Tests/t_ldapobject.py +@@ -334,7 +334,7 @@ class Test00_SimpleLDAPObject(SlapdTestCase): + + @requires_sasl() + @requires_ldapi() +- def test006_sasl_extenal_bind_s(self): ++ def test006_sasl_external_bind_s(self): + l = self.ldap_object_class(self.server.ldapi_uri) + l.sasl_external_bind_s() + self.assertEqual(l.whoami_s(), 'dn:'+self.server.root_dn.lower()) +@@ -343,6 +343,27 @@ class Test00_SimpleLDAPObject(SlapdTestCase): + l.sasl_external_bind_s(authz_id=authz_id) + self.assertEqual(l.whoami_s(), authz_id.lower()) + ++ @requires_sasl() ++ @requires_ldapi() ++ def test006_sasl_options(self): ++ l = self.ldap_object_class(self.server.ldapi_uri) ++ ++ minssf = l.get_option(ldap.OPT_X_SASL_SSF_MIN) ++ self.assertGreaterEqual(minssf, 0) ++ self.assertLessEqual(minssf, 256) ++ maxssf = l.get_option(ldap.OPT_X_SASL_SSF_MAX) ++ self.assertGreaterEqual(maxssf, 0) ++ # libldap sets SSF_MAX to INT_MAX ++ self.assertLessEqual(maxssf, 2**31 - 1) ++ ++ l.set_option(ldap.OPT_X_SASL_SSF_MIN, 56) ++ l.set_option(ldap.OPT_X_SASL_SSF_MAX, 256) ++ self.assertEqual(l.get_option(ldap.OPT_X_SASL_SSF_MIN), 56) ++ self.assertEqual(l.get_option(ldap.OPT_X_SASL_SSF_MAX), 256) ++ ++ l.sasl_external_bind_s() ++ self.assertEqual(l.whoami_s(), 'dn:' + self.server.root_dn.lower()) ++ + def test007_timeout(self): + l = self.ldap_object_class(self.server.ldap_uri) + m = l.search_ext(self.server.suffix, ldap.SCOPE_SUBTREE, '(objectClass=*)') +-- +2.31.1 + diff --git a/python-ldap.spec b/python-ldap.spec index 59db8a6..504275e 100644 --- a/python-ldap.spec +++ b/python-ldap.spec @@ -5,12 +5,14 @@ Name: python-ldap Version: 3.3.1 -Release: 6%{?dist} +Release: 7%{?dist} License: Python Summary: An object-oriented API to access LDAP directory servers URL: https://python-ldap.org/ Source0: https://files.pythonhosted.org/packages/source/p/%{name}/%{name}-%{version}%{?prerelease}.tar.gz +Patch0001: 0001-Fix-SASL-get-set-options-on-big-endian-platforms.patch + ### Build Dependencies ### BuildRequires: gcc BuildRequires: openldap-devel >= %{openldap_version} @@ -49,7 +51,7 @@ Provides: python3-pyldap%{?_isa} = %{version}-%{release} %prep -%setup -q -n %{name}-%{version}%{?prerelease} +%autosetup -p1 -n %{name}-%{version}%{?prerelease} # Fix interpreter find . -name '*.py' | xargs sed -i '1s|^#!/usr/bin/env python|#!%{__python3}|' @@ -77,6 +79,10 @@ PYTHONPATH=%{buildroot}%{python3_sitearch} %{__python3} -m unittest discover -v %{python3_sitearch}/python_ldap-%{version}%{?prerelease}-py%{python3_version}.egg-info/ %changelog +* Mon Jun 28 2021 Christian Heimes - 3.3.1-7 +- Fix SASL get/set options on big endian platforms +- Resolves: rhbz#1976827 + * Tue Jun 22 2021 Mohan Boddu - 3.3.1-6 - Rebuilt for RHEL 9 BETA for openssl 3.0 Related: rhbz#1971065