[PATCH] Port of dsdb, dsdb_dns and samdb Python modules

Andreas Schneider asn at samba.org
Thu Feb 8 09:56:36 UTC 2018


On Wednesday, 7 February 2018 23:37:57 CET Andrew Bartlett wrote:
> I don't think :
> 
> +    def addClenaup(self):
> +        delete_force(self.samdb, self.account_dn)
> 
> Does what you think it does.  (it also isn't spelt correctly)
> 
> See for example how this is done in
> source4/dsdb/tests/python/password_lockout.py
> 
>      self.addCleanup(delete_force, self.ldb, userdn)

Thanks for the hint. Updated patchset attached.


Please review gain.

Thanks,


	Andreas

-- 
Andreas Schneider                   GPG-ID: CC014E3D
Samba Team                             asn at samba.org
www.samba.org
-------------- next part --------------
>From 0e843754b9236dd3ad13779829effe249400dab0 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Tue, 30 Jan 2018 16:39:21 +0100
Subject: [PATCH 1/6] python: Generate random test usernames

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 python/samba/tests/dsdb.py | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/python/samba/tests/dsdb.py b/python/samba/tests/dsdb.py
index 5782eb3ad5a..97d868201d7 100644
--- a/python/samba/tests/dsdb.py
+++ b/python/samba/tests/dsdb.py
@@ -27,6 +27,7 @@ from samba.dcerpc import drsblobs, security
 from samba import dsdb
 import ldb
 import samba
+import uuid
 
 class DsdbTests(TestCase):
 
@@ -41,17 +42,20 @@ class DsdbTests(TestCase):
                            lp=self.lp)
 
         # Create a test user
-        user_name = "samdb-testuser"
+        user_name = "dsdb-user-" + str(uuid.uuid4().hex[0:6])
         user_pass = samba.generate_random_password(32, 32)
         user_description = "Test user for dsdb test"
 
         base_dn = self.samdb.domain_dn()
 
         self.account_dn = "cn=" + user_name + ",cn=Users," + base_dn
-        delete_force(self.samdb, self.account_dn)
         self.samdb.newuser(username=user_name,
                            password=user_pass,
                            description=user_description)
+        self.addCleanup(delete_force, self.samdb, self.account_dn)
+
+    def tearDown(self):
+        delete_force(self.samdb, self.account_dn)
 
     def test_get_oid_from_attrid(self):
         oid = self.samdb.get_oid_from_attid(591614)
-- 
2.16.1


>From 94af21b646b1d277de12ed6dfa11a0028c778ab0 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Tue, 30 Jan 2018 18:09:00 +0100
Subject: [PATCH 2/6] python: Convert base64 encoded password to utf-8

Pair-Programmed-With: Alexander Bokovoy <ab at samba.org>

Signed-off-by: Andreas Schneider <asn at samba.org>
Signed-off-by: Alexander Bokovoy <ab at samba.org>
---
 python/samba/samdb.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/python/samba/samdb.py b/python/samba/samdb.py
index d1048a74e14..0e1b4ae63e6 100644
--- a/python/samba/samdb.py
+++ b/python/samba/samdb.py
@@ -513,7 +513,7 @@ dn: %s
 changetype: modify
 replace: unicodePwd
 unicodePwd:: %s
-""" % (user_dn, base64.b64encode(pw))
+""" % (user_dn, base64.b64encode(pw).decode('utf-8'))
 
             self.modify_ldif(setpw)
 
-- 
2.16.1


>From 5728ff21c3d3f65e30fed6d7ac580bc3e892c68a Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar at redhat.com>
Date: Tue, 30 Jan 2018 18:47:32 +0100
Subject: [PATCH 3/6] python: Port dsdb_dns module to Python 3 compatible form.

Signed-off-by: Lumir Balhar <lbalhar at redhat.com>
---
 source4/dns_server/pydns.c       | 19 ++++++++++++++-----
 source4/dns_server/wscript_build |  8 ++++++--
 2 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/source4/dns_server/pydns.c b/source4/dns_server/pydns.c
index 63fa80e92b3..a4441ddef56 100644
--- a/source4/dns_server/pydns.c
+++ b/source4/dns_server/pydns.c
@@ -20,6 +20,7 @@
 */
 
 #include <Python.h>
+#include "python/py3compat.h"
 #include "includes.h"
 #include <pyldb.h>
 #include <pytalloc.h>
@@ -333,14 +334,22 @@ static PyMethodDef py_dsdb_dns_methods[] = {
 	{ NULL }
 };
 
-void initdsdb_dns(void);
+static struct PyModuleDef moduledef = {
+    PyModuleDef_HEAD_INIT,
+    .m_name = "dsdb_dns",
+    .m_doc = "Python bindings for the DNS objects in the directory service databases.",
+    .m_size = -1,
+    .m_methods = py_dsdb_dns_methods,
+};
 
-void initdsdb_dns(void)
+MODULE_INIT_FUNC(dsdb_dns)
 {
 	PyObject *m;
 
-	m = Py_InitModule3("dsdb_dns", py_dsdb_dns_methods,
-			   "Python bindings for the DNS objects in the directory service databases.");
+	m = PyModule_Create(&moduledef);
+
 	if (m == NULL)
-		return;
+		return NULL;
+
+	return m;
 }
diff --git a/source4/dns_server/wscript_build b/source4/dns_server/wscript_build
index 47701e0f293..c24f45584a4 100644
--- a/source4/dns_server/wscript_build
+++ b/source4/dns_server/wscript_build
@@ -65,8 +65,12 @@ bld.SAMBA_LIBRARY('dlz_bind9_for_torture',
                   deps='samba-hostconfig samdb-common gensec popt dnsserver_common',
                   enabled=bld.AD_DC_BUILD_IS_ENABLED())
 
+for env in bld.gen_python_environments():
+    pyldb_util = bld.pyembed_libname('pyldb-util')
+    pyrpc_util = bld.pyembed_libname('pyrpc_util')
+    pytalloc_util = bld.pyembed_libname('pytalloc-util')
 
-bld.SAMBA_PYTHON('python_dsdb_dns',
+    bld.SAMBA_PYTHON('python_dsdb_dns',
 	         source='pydns.c',
-	         deps='samdb pyldb-util pyrpc_util dnsserver_common pytalloc-util',
+	         deps='samdb %s %s dnsserver_common %s' % (pyldb_util, pyrpc_util, pytalloc_util),
 	         realname='samba/dsdb_dns.so')
-- 
2.16.1


>From d4dbfafed75297513e1d894e2af9a026e737055d Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar at redhat.com>
Date: Tue, 30 Jan 2018 18:52:11 +0100
Subject: [PATCH 4/6] python: Port samdb module to Python 3 compatible form

Signed-off-by: Lumir Balhar <lbalhar at redhat.com>
---
 python/samba/common.py |  2 +-
 python/samba/samdb.py  | 17 +++++++++++------
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/python/samba/common.py b/python/samba/common.py
index a915934f184..1c410a4702d 100644
--- a/python/samba/common.py
+++ b/python/samba/common.py
@@ -18,7 +18,7 @@
 
 
 import ldb
-import dsdb
+from samba import dsdb
 from samba.ndr import ndr_pack
 from samba.dcerpc import misc
 import binascii
diff --git a/python/samba/samdb.py b/python/samba/samdb.py
index 0e1b4ae63e6..05263c79157 100644
--- a/python/samba/samdb.py
+++ b/python/samba/samdb.py
@@ -31,6 +31,7 @@ from samba import dsdb, dsdb_dns
 from samba.ndr import ndr_unpack, ndr_pack
 from samba.dcerpc import drsblobs, misc
 from samba.common import normalise_int32
+from samba.compat import PY3
 
 __docformat__ = "restructuredText"
 
@@ -507,7 +508,11 @@ member: %s
             if len(res) > 1:
                 raise Exception('Matched %u multiple users with filter "%s"' % (len(res), search_filter))
             user_dn = res[0].dn
-            pw = unicode('"' + password.encode('utf-8') + '"', 'utf-8').encode('utf-16-le')
+            print(password, PY3)
+            if PY3:
+                pw = str('"' + password + '"').encode('utf-16-le')
+            else:
+                pw = unicode('"' + password.encode('utf-8') + '"', 'utf-8').encode('utf-16-le')
             setpw = """
 dn: %s
 changetype: modify
@@ -688,7 +693,7 @@ accountExpires: %u
         """
         if len(self.hash_oid_name.keys()) == 0:
             self._populate_oid_attid()
-        if self.hash_oid_name.has_key(self.get_oid_from_attid(attid)):
+        if self.get_oid_from_attid(attid) in self.hash_oid_name:
             return self.hash_oid_name[self.get_oid_from_attid(attid)]
         else:
             return None
@@ -727,14 +732,14 @@ accountExpires: %u
             return None
 
         repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob,
-                            str(res[0]["replPropertyMetaData"]))
+                          res[0]["replPropertyMetaData"][0])
         ctr = repl.ctr
         if len(self.hash_oid_name.keys()) == 0:
             self._populate_oid_attid()
         for o in ctr.array:
             # Search for Description
             att_oid = self.get_oid_from_attid(o.attid)
-            if self.hash_oid_name.has_key(att_oid) and\
+            if att_oid in self.hash_oid_name and\
                att.lower() == self.hash_oid_name[att_oid].lower():
                 return o.version
         return None
@@ -749,7 +754,7 @@ accountExpires: %u
             return None
 
         repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob,
-                            str(res[0]["replPropertyMetaData"]))
+                          res[0]["replPropertyMetaData"][0])
         ctr = repl.ctr
         now = samba.unix2nttime(int(time.time()))
         found = False
@@ -758,7 +763,7 @@ accountExpires: %u
         for o in ctr.array:
             # Search for Description
             att_oid = self.get_oid_from_attid(o.attid)
-            if self.hash_oid_name.has_key(att_oid) and\
+            if att_oid in self.hash_oid_name and\
                att.lower() == self.hash_oid_name[att_oid].lower():
                 found = True
                 seq = self.sequence_number(ldb.SEQ_NEXT)
-- 
2.16.1


>From 8e2dcbfac55ad8a18b2cd9e65a1cb5cdc5b2f2ae Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar at redhat.com>
Date: Tue, 30 Jan 2018 18:53:38 +0100
Subject: [PATCH 5/6] python: Port dsdb module to Python 3 compatible form.

Signed-off-by: Lumir Balhar <lbalhar at redhat.com>
---
 source4/dsdb/pydsdb.c      | 60 +++++++++++++++++++++++++++-------------------
 source4/dsdb/wscript_build | 20 +++++++++-------
 2 files changed, 48 insertions(+), 32 deletions(-)

diff --git a/source4/dsdb/pydsdb.c b/source4/dsdb/pydsdb.c
index 8cf3ef5e4f6..d38d7095efa 100644
--- a/source4/dsdb/pydsdb.c
+++ b/source4/dsdb/pydsdb.c
@@ -18,6 +18,7 @@
 */
 
 #include <Python.h>
+#include "python/py3compat.h"
 #include "includes.h"
 #include <ldb.h>
 #include <pyldb.h>
@@ -32,7 +33,6 @@
 #include "lib/util/dlinklist.h"
 #include "dsdb/kcc/garbage_collect_tombstones.h"
 
-void initdsdb(void);
 
 /* FIXME: These should be in a header file somewhere */
 #define PyErr_LDB_OR_RAISE(py_ldb, ldb) \
@@ -93,7 +93,7 @@ static PyObject *py_samdb_server_site_name(PyObject *self, PyObject *args)
 		return NULL;
 	}
 
-	result = PyString_FromString(site);
+	result = PyStr_FromString(site);
 	talloc_free(mem_ctx);
 	return result;
 }
@@ -119,7 +119,7 @@ static PyObject *py_dsdb_convert_schema_to_openldap(PyObject *self,
 		return NULL;
 	} 
 
-	ret = PyString_FromString(retstr);
+	ret = PyStr_FromString(retstr);
 	talloc_free(retstr);
 	return ret;
 }
@@ -136,7 +136,7 @@ static PyObject *py_samdb_set_domain_sid(PyLdbObject *self, PyObject *args)
 	
 	PyErr_LDB_OR_RAISE(py_ldb, ldb);
 
-	sid = dom_sid_parse_talloc(NULL, PyString_AsString(py_sid));
+	sid = dom_sid_parse_talloc(NULL, PyStr_AsString(py_sid));
 	if (sid == NULL) {
 		PyErr_NoMemory();
 		return NULL;
@@ -209,7 +209,7 @@ static PyObject *py_samdb_get_domain_sid(PyLdbObject *self, PyObject *args)
 		PyErr_NoMemory();
 		return NULL;
 	}
-	ret = PyString_FromString(retstr);
+	ret = PyStr_FromString(retstr);
 	talloc_free(retstr);
 	return ret;
 }
@@ -239,7 +239,7 @@ static PyObject *py_samdb_ntds_invocation_id(PyObject *self, PyObject *args)
 		PyErr_NoMemory();
 		return NULL;
 	}
-	result = PyString_FromString(retstr);
+	result = PyStr_FromString(retstr);
 	talloc_free(retstr);
 	return result;
 }
@@ -281,7 +281,7 @@ static PyObject *py_dsdb_get_oid_from_attid(PyObject *self, PyObject *args)
 		return NULL;
 	}
 
-	ret = PyString_FromString(oid);
+	ret = PyStr_FromString(oid);
 
 	talloc_free(mem_ctx);
 
@@ -436,7 +436,7 @@ static PyObject *py_dsdb_get_backlink_from_lDAPDisplayName(PyObject *self, PyObj
 		Py_RETURN_NONE;
 	}
 
-	return PyString_FromString(target_attr->lDAPDisplayName);
+	return PyStr_FromString(target_attr->lDAPDisplayName);
 }
 
 
@@ -466,7 +466,7 @@ static PyObject *py_dsdb_get_lDAPDisplayName_by_attid(PyObject *self, PyObject *
 		return NULL;
 	}
 
-	return PyString_FromString(a->lDAPDisplayName);
+	return PyStr_FromString(a->lDAPDisplayName);
 }
 
 
@@ -499,7 +499,7 @@ static PyObject *py_dsdb_get_syntax_oid_from_lDAPDisplayName(PyObject *self, PyO
 		return NULL;
 	}
 
-	return PyString_FromString(attribute->syntax->ldap_oid);
+	return PyStr_FromString(attribute->syntax->ldap_oid);
 }
 
 /*
@@ -518,6 +518,7 @@ static PyObject *py_dsdb_DsReplicaAttribute(PyObject *self, PyObject *args)
 	TALLOC_CTX *tmp_ctx;
 	WERROR werr;
 	Py_ssize_t i;
+	Py_ssize_t _size;
 
 	if (!PyArg_ParseTuple(args, "OsO", &py_ldb, &ldap_display_name, &el_list)) {
 		return NULL;
@@ -579,13 +580,13 @@ static PyObject *py_dsdb_DsReplicaAttribute(PyObject *self, PyObject *args)
 
 		for (i = 0; i < el->num_values; i++) {
 			PyObject *item = PyList_GetItem(el_list, i);
-			if (!PyString_Check(item)) {
+			if (!PyStr_Check(item)) {
 				PyErr_Format(PyExc_TypeError, "ldif_elements should be strings");
 				talloc_free(tmp_ctx);
 				return NULL;
 			}
-			el->values[i].data = (uint8_t *)PyString_AsString(item);
-			el->values[i].length = PyString_Size(item);
+			el->values[i].data = (uint8_t *)PyStr_AsUTF8AndSize(item, &_size);
+			el->values[i].length = _size;
 		}
 	}
 
@@ -624,6 +625,7 @@ static PyObject *py_dsdb_normalise_attributes(PyObject *self, PyObject *args)
 	TALLOC_CTX *tmp_ctx;
 	WERROR werr;
 	Py_ssize_t i;
+	Py_ssize_t _size;
 	PyTypeObject *py_type = NULL;
 	PyObject *module = NULL;
 
@@ -686,13 +688,13 @@ static PyObject *py_dsdb_normalise_attributes(PyObject *self, PyObject *args)
 
 		for (i = 0; i < el->num_values; i++) {
 			PyObject *item = PyList_GetItem(el_list, i);
-			if (!PyString_Check(item)) {
+			if (!PyStr_Check(item)) {
 				PyErr_Format(PyExc_TypeError, "ldif_elements should be strings");
 				talloc_free(tmp_ctx);
 				return NULL;
 			}
-			el->values[i].data = (uint8_t *)PyString_AsString(item);
-			el->values[i].length = PyString_Size(item);
+			el->values[i].data = (uint8_t *)PyStr_AsUTF8AndSize(item, &_size);;
+			el->values[i].length = _size;
 		}
 	}
 
@@ -767,7 +769,7 @@ static PyObject *py_dsdb_set_ntds_invocation_id(PyObject *self, PyObject *args)
 		return NULL;
 
 	PyErr_LDB_OR_RAISE(py_ldb, ldb);
-	GUID_from_string(PyString_AsString(py_guid), &guid);
+	GUID_from_string(PyStr_AsString(py_guid), &guid);
 
 	if (GUID_all_zero(&guid)) {
 		PyErr_SetString(PyExc_RuntimeError, "set_ntds_invocation_id rejected due to all-zero invocation ID");
@@ -806,7 +808,7 @@ static PyObject *py_samdb_ntds_objectGUID(PyObject *self, PyObject *args)
 		PyErr_NoMemory();
 		return NULL;
 	}
-	result = PyString_FromString(retstr);
+	result = PyStr_FromString(retstr);
 	talloc_free(retstr);
 	return result;
 }
@@ -1200,7 +1202,7 @@ static PyObject *py_dsdb_garbage_collect_tombstones(PyObject *self, PyObject *ar
 	length = PyList_GET_SIZE(py_list_dn);
 
 	for (i = 0; i < length; i++) {
-		char *part_str = PyString_AsString(PyList_GetItem(py_list_dn, i));
+		char *part_str = PyStr_AsString(PyList_GetItem(py_list_dn, i));
 		struct ldb_dn *p;
 		struct dsdb_ldb_dn_list_node *node;
 
@@ -1389,14 +1391,22 @@ static PyMethodDef py_dsdb_methods[] = {
 	{ NULL }
 };
 
-void initdsdb(void)
+static struct PyModuleDef moduledef = {
+    PyModuleDef_HEAD_INIT,
+    .m_name = "dsdb",
+    .m_doc = "Python bindings for the directory service databases.",
+    .m_size = -1,
+    .m_methods = py_dsdb_methods,
+};
+
+MODULE_INIT_FUNC(dsdb)
 {
 	PyObject *m;
 
-	m = Py_InitModule3("dsdb", py_dsdb_methods, 
-			   "Python bindings for the directory service databases.");
+	m = PyModule_Create(&moduledef);
+
 	if (m == NULL)
-		return;
+		return NULL;
 
 #define ADD_DSDB_FLAG(val)  PyModule_AddObject(m, #val, PyInt_FromLong(val))
 
@@ -1562,7 +1572,7 @@ void initdsdb(void)
 	ADD_DSDB_FLAG(GPO_INHERIT);
 	ADD_DSDB_FLAG(GPO_BLOCK_INHERITANCE);
 
-#define ADD_DSDB_STRING(val)  PyModule_AddObject(m, #val, PyString_FromString(val))
+#define ADD_DSDB_STRING(val)  PyModule_AddObject(m, #val, PyStr_FromString(val))
 
 	ADD_DSDB_STRING(DSDB_SYNTAX_BINARY_DN);
 	ADD_DSDB_STRING(DSDB_SYNTAX_STRING_DN);
@@ -1586,4 +1596,6 @@ void initdsdb(void)
 	ADD_DSDB_STRING(DS_GUID_PROGRAM_DATA_CONTAINER);
 	ADD_DSDB_STRING(DS_GUID_SYSTEMS_CONTAINER);
 	ADD_DSDB_STRING(DS_GUID_USERS_CONTAINER);
+
+	return m;
 }
diff --git a/source4/dsdb/wscript_build b/source4/dsdb/wscript_build
index 29c6f0e4a70..e1f1e61c55e 100644
--- a/source4/dsdb/wscript_build
+++ b/source4/dsdb/wscript_build
@@ -62,11 +62,15 @@ bld.SAMBA_MODULE('service_dns_update',
 	enabled=bld.AD_DC_BUILD_IS_ENABLED()
 	)
 
-bld.SAMBA_PYTHON('python_dsdb',
-	source='pydsdb.c',
-	# the dependency on dcerpc here is because gensec
-	# depends on dcerpc but the waf circular dependency finder
-	# removes it so we end up with unresolved symbols.
-	deps='samdb pyldb-util dcerpc com_err pyrpc_util pyparam_util dsdb_garbage_collect_tombstones',
-	realname='samba/dsdb.so'
-	)
+for env in bld.gen_python_environments():
+	pyldb_util = bld.pyembed_libname('pyldb-util')
+	pyrpc_util = bld.pyembed_libname('pyrpc_util')
+	pyparam_util = bld.pyembed_libname('pyparam_util')
+	bld.SAMBA_PYTHON('python_dsdb',
+		source='pydsdb.c',
+		# the dependency on dcerpc here is because gensec
+		# depends on dcerpc but the waf circular dependency finder
+		# removes it so we end up with unresolved symbols.
+		deps='samdb %s dcerpc com_err %s %s dsdb_garbage_collect_tombstones' % (pyldb_util, pyrpc_util, pyparam_util),
+		realname='samba/dsdb.so'
+		)
-- 
2.16.1


>From 1f1af4784cb31e157c99e9069502967645b2b51d Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar at redhat.com>
Date: Tue, 30 Jan 2018 18:55:12 +0100
Subject: [PATCH 6/6] python: tests: Make tests of dsdb Python module Python 3
 compatible

Signed-off-by: Lumir Balhar <lbalhar at redhat.com>
---
 python/samba/tests/dsdb.py | 23 ++++++++++++-----------
 source4/selftest/tests.py  |  2 +-
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/python/samba/tests/dsdb.py b/python/samba/tests/dsdb.py
index 97d868201d7..ff5fbfd5673 100644
--- a/python/samba/tests/dsdb.py
+++ b/python/samba/tests/dsdb.py
@@ -66,7 +66,7 @@ class DsdbTests(TestCase):
                                 base=self.account_dn,
                                 attrs=["replPropertyMetaData"])
         repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob,
-                            str(res[0]["replPropertyMetaData"]))
+                          res[0]["replPropertyMetaData"][0])
         ctr = repl.ctr
         for o in ctr.array:
             # Search for Description
@@ -84,7 +84,7 @@ class DsdbTests(TestCase):
                                 base=self.account_dn,
                                 attrs=["replPropertyMetaData"])
         repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob,
-                            str(res[0]["replPropertyMetaData"]))
+                          res[0]["replPropertyMetaData"][0])
         replBlob = ndr_pack(repl)
         msg = ldb.Message()
         msg.dn = res[0].dn
@@ -96,7 +96,7 @@ class DsdbTests(TestCase):
                                 base=self.account_dn,
                                 attrs=["replPropertyMetaData"])
         repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob,
-                            str(res[0]["replPropertyMetaData"]))
+                          res[0]["replPropertyMetaData"][0])
         replBlob = ndr_pack(repl)
         msg = ldb.Message()
         msg.dn = res[0].dn
@@ -108,14 +108,14 @@ class DsdbTests(TestCase):
                                 base=self.account_dn,
                                 attrs=["replPropertyMetaData", "uSNChanged"])
         repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob,
-                            str(res[0]["replPropertyMetaData"]))
+                          res[0]["replPropertyMetaData"][0])
         ctr = repl.ctr
         for o in ctr.array:
             # Search for Description
             if o.attid == 13:
                 old_version = o.version
                 o.version = o.version + 1
-                o.local_usn = long(str(res[0]["uSNChanged"])) + 1
+                o.local_usn = int(str(res[0]["uSNChanged"])) + 1
         replBlob = ndr_pack(repl)
         msg = ldb.Message()
         msg.dn = res[0].dn
@@ -128,15 +128,15 @@ class DsdbTests(TestCase):
                                 base=self.account_dn,
                                 attrs=["replPropertyMetaData", "uSNChanged"])
         repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob,
-                            str(res[0]["replPropertyMetaData"]))
+                          res[0]["replPropertyMetaData"][0])
         ctr = repl.ctr
         for o in ctr.array:
             # Search for Description
             if o.attid == 13:
                 old_version = o.version
                 o.version = o.version + 1
-                o.local_usn = long(str(res[0]["uSNChanged"])) + 1
-                o.originating_usn = long(str(res[0]["uSNChanged"])) + 1
+                o.local_usn = int(str(res[0]["uSNChanged"])) + 1
+                o.originating_usn = int(str(res[0]["uSNChanged"])) + 1
         replBlob = ndr_pack(repl)
         msg = ldb.Message()
         msg.dn = res[0].dn
@@ -185,7 +185,8 @@ class DsdbTests(TestCase):
                                     controls=["local_oid:%s:1"
                                               % dsdb.DSDB_CONTROL_INVALID_NOT_IMPLEMENTED])
         except ldb.LdbError as e:
-            if e[0] != ldb.ERR_UNSUPPORTED_CRITICAL_EXTENSION:
+            (errno, estr) = e.args
+            if errno != ldb.ERR_UNSUPPORTED_CRITICAL_EXTENSION:
                 self.fail("Got %s should have got ERR_UNSUPPORTED_CRITICAL_EXTENSION"
                           % e[1])
 
@@ -229,7 +230,7 @@ class DsdbTests(TestCase):
                 "dn": dn,
                 "objectClass": "foreignSecurityPrincipal"})
         except ldb.LdbError as e:
-            (code, msg) = e
+            (code, msg) = e.args
             self.fail("Got unexpected exception %d - %s "
                       % (code, msg))
 
@@ -264,7 +265,7 @@ class DsdbTests(TestCase):
                 "objectSID": sid})
             self.fail("No exception should get LDB_ERR_CONSTRAINT_VIOLATION")
         except ldb.LdbError as e:
-            (code, msg) = e
+            (code, msg) = e.args
             if code != ldb.ERR_CONSTRAINT_VIOLATION:
                 self.fail("Got %d - %s should have got "
                           "LDB_ERR_CONSTRAINT_VIOLATION"
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index de0bbeadc08..c64101ff463 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -577,7 +577,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex
 planoldpythontestsuite("ad_dc_ntvfs:local", "samba.tests.gensec", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True)
 planoldpythontestsuite("none", "simple", extra_path=["%s/lib/tdb/python/tests" % srcdir()], name="tdb.python")
 planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.sam")
-planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dsdb")
+planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dsdb", py3_compatible=True)
 planpythontestsuite("none", "samba.tests.dsdb_lock")
 planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.bare")
 planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.unix")
-- 
2.16.1



More information about the samba-technical mailing list