PATCH: python3 smb module

David Mulder dmulder at suse.com
Mon Feb 12 15:30:28 UTC 2018


Noel's patch, plus a test case that runs on both py2 and py3.


On 01/17/2018 03:32 AM, Noel Power via samba-technical wrote:
> Before Christmas playing with something where I needed to play with
> samba + python3 I found the smb module was not ported, I scratched
> together a patch (and forgot about it 'till the recent python3 porting
> messages :-)) Please have a look, comments and corrections welcome
>
> Noel
>

-- 
David Mulder
SUSE Labs Software Engineer - Samba
dmulder at suse.com
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)

-------------- next part --------------
From aef77fb3516629c915e9f5630c8a7e310c9dbd13 Mon Sep 17 00:00:00 2001
From: Noel Power <noel.power at suse.com>
Date: Thu, 14 Dec 2017 11:32:23 +0000
Subject: [PATCH 1/2] s4/libcli: python3 port for smb module

Signed-off-by: Noel Power <noel.power at suse.com>
---
 source4/libcli/pysmb.c       | 26 +++++++++++++++++++-------
 source4/libcli/wscript_build | 14 ++++++++------
 2 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/source4/libcli/pysmb.c b/source4/libcli/pysmb.c
index 10ab54a9338..cc0d0f3bf7a 100644
--- a/source4/libcli/pysmb.c
+++ b/source4/libcli/pysmb.c
@@ -18,6 +18,7 @@
 */
 
 #include <Python.h>
+#include "python/py3compat.h"
 #include <tevent.h>
 #include <pytalloc.h>
 #include "includes.h"
@@ -157,11 +158,11 @@ static void py_smb_list_callback(struct clilist_file_info *f, const char *mask,
 
 		dict = PyDict_New();
 		if(dict) {
-			PyDict_SetItemString(dict, "name", PyString_FromString(f->name));
+			PyDict_SetItemString(dict, "name", PyStr_FromString(f->name));
 			
 			/* Windows does not always return short_name */
 			if (f->short_name) {
-				PyDict_SetItemString(dict, "short_name", PyString_FromString(f->short_name));
+				PyDict_SetItemString(dict, "short_name", PyStr_FromString(f->short_name));
 			} else {
 				PyDict_SetItemString(dict, "short_name", Py_None);
 			}
@@ -651,17 +652,27 @@ static PyTypeObject PySMB = {
 
 };
 
-void initsmb(void)
+static struct PyModuleDef moduledef = {
+    PyModuleDef_HEAD_INIT,
+    .m_name = "smb",
+    .m_doc = "SMB File I/O support",
+    .m_size = -1,
+    .m_methods = py_smb_methods,
+};
+
+void initsmb(void);
+
+MODULE_INIT_FUNC(smb)
 {
-	PyObject *m;
+	PyObject *m = NULL;
 
 	if (pytalloc_BaseObject_PyType_Ready(&PySMB) < 0) {
-		return;
+		return m;
 	}
 
-	m = Py_InitModule3("smb", NULL, "SMB File I/O support");
+	m = PyModule_Create(&moduledef);
 	if (m == NULL) {
-	    return;
+	    return m;
 	}
 
 	Py_INCREF(&PySMB);
@@ -685,4 +696,5 @@ void initsmb(void)
 	ADD_FLAGS(FILE_ATTRIBUTE_NONINDEXED);
 	ADD_FLAGS(FILE_ATTRIBUTE_ENCRYPTED);
 	ADD_FLAGS(FILE_ATTRIBUTE_ALL_MASK);
+	return m;
 }
diff --git a/source4/libcli/wscript_build b/source4/libcli/wscript_build
index 38a8f4e0718..a8863292ad7 100644
--- a/source4/libcli/wscript_build
+++ b/source4/libcli/wscript_build
@@ -31,12 +31,14 @@ bld.SAMBA_SUBSYSTEM('LIBCLI_SMB_COMPOSITE',
 	private_headers='smb_composite/smb_composite.h',
 	)
 
-bld.SAMBA_PYTHON('pysmb',
-    source='pysmb.c',
-    deps='LIBCLI_SMB_COMPOSITE LIBCLI_SMB2 tevent-util pyparam_util pytalloc-util',
-	public_deps='cli_composite samba-credentials gensec LIBCLI_RESOLVE tevent param_options',
-    realname='samba/smb.so'
-    )
+
+for env in bld.gen_python_environments():
+	bld.SAMBA_PYTHON('pysmb',
+		source='pysmb.c',
+		deps='LIBCLI_SMB_COMPOSITE LIBCLI_SMB2 tevent-util pyparam_util pytalloc-util',
+		public_deps='cli_composite samba-credentials gensec LIBCLI_RESOLVE tevent param_options',
+		realname='samba/smb.so'
+	)
 
 bld.SAMBA_SUBSYSTEM('LIBCLI_DGRAM',
 	source='dgram/dgramsocket.c dgram/mailslot.c dgram/netlogon.c dgram/browse.c',
-- 
2.13.6


From eb5123620727a76041618838d335e156975fe87e Mon Sep 17 00:00:00 2001
From: David Mulder <dmulder at suse.com>
Date: Fri, 9 Feb 2018 08:42:18 -0700
Subject: [PATCH 2/2] python: create test for pysmb module

Signed-off-by: David Mulder <dmulder at suse.com>
---
 python/samba/tests/smb.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++
 source4/selftest/tests.py |  3 +++
 2 files changed, 57 insertions(+)
 create mode 100644 python/samba/tests/smb.py

diff --git a/python/samba/tests/smb.py b/python/samba/tests/smb.py
new file mode 100644
index 00000000000..d7a78ff2920
--- /dev/null
+++ b/python/samba/tests/smb.py
@@ -0,0 +1,54 @@
+# -*- coding: utf-8 -*-
+import samba, os, random, sys
+from samba import smb
+
+PY3 = sys.version_info[0] == 3
+addom = 'addom.samba.example.com/'
+sysvolfile = os.path.join(addom,
+                'Policies/{31B2F340-016D-11D2-945F-00C04FB984F9}/GPT.INI')
+test_contents = 'abcd'*256
+utf_contents = u'Süßigkeiten Äpfel '*128
+test_dir = os.path.join(addom, 'testing_%d' % random.randint(0,0xFFFF))
+
+class SMBTests(samba.tests.TestCase):
+    def setUp(self):
+        super(SMBTests, self).setUp()
+        self.server = os.environ["SERVER"]
+        creds = self.insta_creds(template=self.get_credentials())
+        self.conn = smb.SMB(self.server,
+                            "sysvol",
+                            lp=self.get_loadparm(),
+                            creds=creds)
+
+    def tearDown(self):
+        global test_dir
+        super(SMBTests, self).tearDown()
+        try:
+            self.conn.deltree(test_dir)
+        except:
+            pass
+
+    def test_list(self):
+        global addom
+        ls = [f['name'] for f in self.conn.list(addom)]
+        assert 'scripts' in ls, '"scripts" directory not found in sysvol'
+        assert 'Policies' in ls, '"Policies" directory not found in sysvol'
+
+    def test_save_load(self):
+        global test_dir, test_contents, utf_contents
+        self.conn.mkdir(test_dir)
+
+        test_file = os.path.join(test_dir, 'testing').replace('/', '\\')
+        self.conn.savefile(test_file, test_contents)
+
+        contents = self.conn.loadfile(test_file)
+        assert contents == test_contents, \
+            'contents of test file did not match what was written'
+
+        if PY3:
+            self.conn.savefile(test_file, utf_contents)
+
+            contents = self.conn.loadfile(test_file)
+            assert contents == utf_contents, \
+                'contents of test file did not match what was written'
+
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index 22087c6e785..ed232a02d03 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -617,6 +617,9 @@ planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.sites")
 planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.dnscmd")
 
 planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.rpcecho")
+
+planoldpythontestsuite("ad_dc:local", "samba.tests.smb", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True)
+
 planoldpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.registry", extra_args=['-U"$USERNAME%$PASSWORD"'])
 planoldpythontestsuite("ad_dc_ntvfs", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"'])
 planoldpythontestsuite("ad_dc", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"'])
-- 
2.13.6



More information about the samba-technical mailing list