From 12a2bdab56a73fb4708fceb97ab0d735d832acc2 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 4 May 2018 11:49:23 +0100 Subject: [PATCH 001/122] python/samba/tests: Ensure StringIO usage is py2/py3 compatible Signed-off-by: Noel Power --- python/samba/gpclass.py | 2 +- python/samba/tests/blackbox/samba_dnsupdate.py | 2 +- python/samba/tests/emulate/traffic.py | 2 +- python/samba/tests/netcmd.py | 2 +- python/samba/tests/samba_tool/base.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/python/samba/gpclass.py b/python/samba/gpclass.py index 0966611b686..d9ffad2165f 100644 --- a/python/samba/gpclass.py +++ b/python/samba/gpclass.py @@ -21,7 +21,7 @@ sys.path.insert(0, "bin/python") from samba import NTSTATUSError from ConfigParser import ConfigParser -from StringIO import StringIO +from samba.compat import StringIO from abc import ABCMeta, abstractmethod import xml.etree.ElementTree as etree import re diff --git a/python/samba/tests/blackbox/samba_dnsupdate.py b/python/samba/tests/blackbox/samba_dnsupdate.py index e6cad3bbaba..1a659b0b423 100644 --- a/python/samba/tests/blackbox/samba_dnsupdate.py +++ b/python/samba/tests/blackbox/samba_dnsupdate.py @@ -17,7 +17,7 @@ # import samba.tests -from StringIO import StringIO +from samba.compat import StringIO from samba.netcmd.main import cmd_sambatool from samba.credentials import Credentials from samba.auth import system_session diff --git a/python/samba/tests/emulate/traffic.py b/python/samba/tests/emulate/traffic.py index a57c2f5bc4e..0cfae02bce0 100644 --- a/python/samba/tests/emulate/traffic.py +++ b/python/samba/tests/emulate/traffic.py @@ -16,7 +16,7 @@ # along with this program. If not, see . # from pprint import pprint -from cStringIO import StringIO +from samba.compat import StringIO import samba.tests diff --git a/python/samba/tests/netcmd.py b/python/samba/tests/netcmd.py index 2867c031a17..6f5ea88eb99 100644 --- a/python/samba/tests/netcmd.py +++ b/python/samba/tests/netcmd.py @@ -17,7 +17,7 @@ """Tests for samba.netcmd.""" -from cStringIO import StringIO +from samba.compat import StringIO from samba.netcmd import Command from samba.netcmd.testparm import cmd_testparm from samba.netcmd.main import cmd_sambatool diff --git a/python/samba/tests/samba_tool/base.py b/python/samba/tests/samba_tool/base.py index 06e19c19087..71c8ecb20d3 100644 --- a/python/samba/tests/samba_tool/base.py +++ b/python/samba/tests/samba_tool/base.py @@ -25,7 +25,7 @@ import string from samba.auth import system_session from samba.samdb import SamDB -from cStringIO import StringIO +from samba.compat import StringIO from samba.netcmd.main import cmd_sambatool import samba.tests From fa1e14ba398f599d83a57ce64ed187c6ca60c1b3 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 30 Apr 2018 15:46:04 +0100 Subject: [PATCH 002/122] python/samba: Fix py2/3 relative module import issue --- python/samba/netcmd/nettime.py | 2 +- python/samba/subnets.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/samba/netcmd/nettime.py b/python/samba/netcmd/nettime.py index 694b6adda9b..7c16aec92f3 100644 --- a/python/samba/netcmd/nettime.py +++ b/python/samba/netcmd/nettime.py @@ -17,7 +17,7 @@ # import samba.getopt as options -import common +from . import common from samba.net import Net from samba.netcmd import ( diff --git a/python/samba/subnets.py b/python/samba/subnets.py index 32865bc3bcd..5be2679374e 100644 --- a/python/samba/subnets.py +++ b/python/samba/subnets.py @@ -22,7 +22,7 @@ import ldb from ldb import FLAG_MOD_ADD, FLAG_MOD_REPLACE, LdbError -from sites import SiteNotFoundException +from .sites import SiteNotFoundException class SubnetException(Exception): """Base element for Subnet errors""" From 4157479696a2b6b010369163d50c488f5ddc8e67 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Sat, 5 May 2018 11:38:45 +0100 Subject: [PATCH 003/122] maybe missing samba.tests.dsdb_lock tweaks (seems to have been lost in the rebase) --- python/samba/dbchecker.py | 2 +- python/samba/ms_display_specifiers.py | 3 ++- python/samba/ms_schema.py | 3 ++- python/samba/provision/__init__.py | 11 ++++++----- python/samba/samdb.py | 4 ++-- python/samba/schema.py | 2 +- 6 files changed, 14 insertions(+), 11 deletions(-) diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py index 9d72fc6ca94..5e486c41d33 100644 --- a/python/samba/dbchecker.py +++ b/python/samba/dbchecker.py @@ -293,7 +293,7 @@ def check_deleted_objects_containers(self): # as the original one, so that on replication we # merge, rather than conflict. proposed_objectguid = dsdb_dn.dn.get_extended_component("GUID") - listwko.append(o) + listwko.append(o.decode('utf8')) if proposed_objectguid is not None: guid_suffix = "\nobjectGUID: %s" % str(misc.GUID(proposed_objectguid)) diff --git a/python/samba/ms_display_specifiers.py b/python/samba/ms_display_specifiers.py index 0d7b39aaae9..3cba837c652 100644 --- a/python/samba/ms_display_specifiers.py +++ b/python/samba/ms_display_specifiers.py @@ -169,7 +169,8 @@ def read_ms_ldif(filename): out = [] - f = open(filename, "rU") + from io import open + f = open(filename, "r", encoding='latin-1') for entry in __read_raw_entries(f): out.append(__write_ldif_one(__transform_entry(entry))) diff --git a/python/samba/ms_schema.py b/python/samba/ms_schema.py index e8363754281..e847cf62c58 100644 --- a/python/samba/ms_schema.py +++ b/python/samba/ms_schema.py @@ -291,7 +291,8 @@ def __parse_schema_file(filename, objectClass): out = [] - f = open(filename, "rU") + from io import open + f = open(filename, "r", encoding='latin-1') for entry in __read_raw_entries(f): out.append(__write_ldif_one(__transform_entry(entry, objectClass))) diff --git a/python/samba/provision/__init__.py b/python/samba/provision/__init__.py index d9df425655f..7fa039d0316 100644 --- a/python/samba/provision/__init__.py +++ b/python/samba/provision/__init__.py @@ -27,6 +27,7 @@ __docformat__ = "restructuredText" from samba.compat import urllib_quote +from samba.compat import string_types from base64 import b64encode import errno import os @@ -1070,7 +1071,7 @@ def setup_encrypted_secrets_key(path): finally: os.umask(umask_original) - with os.fdopen(fd, 'w') as f: + with os.fdopen(fd, 'wb') as f: key = samba.generate_random_bytes(16) f.write(key) @@ -1561,8 +1562,8 @@ def fill_samdb(samdb, lp, names, logger, policyguid, ntds_dn = "CN=NTDS Settings,%s" % names.serverdn names.ntdsguid = samdb.searchone(basedn=ntds_dn, - attribute="objectGUID", expression="", scope=ldb.SCOPE_BASE) - assert isinstance(names.ntdsguid, str) + attribute="objectGUID", expression="", scope=ldb.SCOPE_BASE).decode('utf8') + assert isinstance(names.ntdsguid, string_types) return samdb @@ -1938,8 +1939,8 @@ def provision_fill(samdb, secrets_ldb, logger, names, paths, backend_store=backend_store) domainguid = samdb.searchone(basedn=samdb.get_default_basedn(), - attribute="objectGUID") - assert isinstance(domainguid, str) + attribute="objectGUID").decode('utf8') + assert isinstance(domainguid, string_types) lastProvisionUSNs = get_last_provision_usn(samdb) maxUSN = get_max_usn(samdb, str(names.rootdn)) diff --git a/python/samba/samdb.py b/python/samba/samdb.py index 7184fcfa4b0..d4e1272bddc 100644 --- a/python/samba/samdb.py +++ b/python/samba/samdb.py @@ -1041,12 +1041,12 @@ def sequence_number(self, seq_type): def get_dsServiceName(self): '''get the NTDS DN from the rootDSE''' res = self.search(base="", scope=ldb.SCOPE_BASE, attrs=["dsServiceName"]) - return res[0]["dsServiceName"][0] + return res[0]["dsServiceName"][0].decode('utf8') def get_serverName(self): '''get the server DN from the rootDSE''' res = self.search(base="", scope=ldb.SCOPE_BASE, attrs=["serverName"]) - return res[0]["serverName"][0] + return res[0]["serverName"][0].decode('utf8') def dns_lookup(self, dns_name, dns_partition=None): '''Do a DNS lookup in the database, returns the NDR database structures''' diff --git a/python/samba/schema.py b/python/samba/schema.py index c5537080296..ec98b37d8ba 100644 --- a/python/samba/schema.py +++ b/python/samba/schema.py @@ -130,7 +130,7 @@ def __init__(self, domain_sid, invocationid=None, schemadn=None, if override_prefixmap is not None: self.prefixmap_data = override_prefixmap else: - self.prefixmap_data = open(setup_path("prefixMap.txt"), 'r').read() + self.prefixmap_data = open(setup_path("prefixMap.txt"), 'rb').read() if additional_prefixmap is not None: for map in additional_prefixmap: From 595f5292f8049e4a9f028937fcb1bc5bc179324c Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 10 Apr 2018 16:03:37 +0100 Subject: [PATCH 004/122] s4/selftest: enable samba.tests.dsdb_lock for python3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 535931663b8..6c60852c152 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -586,7 +586,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planoldpythontestsuite("none", "simple", extra_path=["%s/lib/tdb/python/tests" % srcdir()], name="tdb.python") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.sam", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dsdb", py3_compatible=True) -planpythontestsuite("none", "samba.tests.dsdb_lock") +planpythontestsuite("none", "samba.tests.dsdb_lock", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.bare", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.unix") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.srvsvc") From b8b9adb04070f03824afe5c1c2294a789ab14766 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 17 Apr 2018 11:56:40 +0100 Subject: [PATCH 005/122] python/samba/tests: port samba.tests.unix for py3 Signed-off-by: Noel Power --- python/samba/tests/dcerpc/unix.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/python/samba/tests/dcerpc/unix.py b/python/samba/tests/dcerpc/unix.py index e8ef4da8630..67bf043bc92 100644 --- a/python/samba/tests/dcerpc/unix.py +++ b/python/samba/tests/dcerpc/unix.py @@ -20,6 +20,9 @@ from samba.dcerpc import unixinfo from samba.tests import RpcInterfaceTestCase +from samba.compat import text_type as txt_type +from samba.compat import PY3 as is_py3 +import samba.compat class UnixinfoTests(RpcInterfaceTestCase): @@ -31,16 +34,18 @@ def test_getpwuid_int(self): infos = self.conn.GetPWUid(range(512)) self.assertEquals(512, len(infos)) self.assertEquals("/bin/false", infos[0].shell) - self.assertTrue(isinstance(infos[0].homedir, unicode)) + self.assertTrue(isinstance(infos[0].homedir, txt_type)) def test_getpwuid(self): - infos = self.conn.GetPWUid(map(long, range(512))) - self.assertEquals(512, len(infos)) - self.assertEquals("/bin/false", infos[0].shell) - self.assertTrue(isinstance(infos[0].homedir, unicode)) + # This test only relevant in PY2 + if not is_py3: + infos = self.conn.GetPWUid(map(long, range(512))) + self.assertEquals(512, len(infos)) + self.assertEquals("/bin/false", infos[0].shell) + self.assertTrue(isinstance(infos[0].homedir, txt_type)) def test_gidtosid(self): - self.conn.GidToSid(1000L) + self.conn.GidToSid(1000) def test_uidtosid(self): self.conn.UidToSid(1000) From 6c661e189681835e1c9a69e6c6eb15b55d1ef12e Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 16 Apr 2018 18:58:01 +0100 Subject: [PATCH 006/122] s4/selftest: enable samba.tests.dcerpc.unix for python3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 6c60852c152..3624ffcf1f1 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -588,7 +588,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dsdb", py3_compatible=True) planpythontestsuite("none", "samba.tests.dsdb_lock", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.bare", py3_compatible=True) -planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.unix") +planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.unix", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.srvsvc") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.timecmd") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.join") From 1159d0225f1004a5f8918f602ef5eaac961938ba Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 17 Apr 2018 13:53:57 +0100 Subject: [PATCH 007/122] s4/selftest/tests: enable samba.tests.samba_tool.timecmd for python3 --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 3624ffcf1f1..8f855344766 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -590,7 +590,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.bare", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.unix", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.srvsvc") -planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.timecmd") +planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.timecmd", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.join") planpythontestsuite("none", "samba.tests.samba_tool.visualize") From 5276a8701cdb8293c5459c33c1d0a4b1771e2e2e Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 17 Apr 2018 16:48:03 +0100 Subject: [PATCH 008/122] python/samba: changes to make samba.tests.samba_tool.join run under py3 --- python/samba/join.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/samba/join.py b/python/samba/join.py index dc6d234d0ed..ff8d18a27fd 100644 --- a/python/samba/join.py +++ b/python/samba/join.py @@ -358,21 +358,21 @@ def get_behavior_version(ctx): def get_dnsHostName(ctx): res = ctx.samdb.search(base="", scope=ldb.SCOPE_BASE, attrs=["dnsHostName"]) - return res[0]["dnsHostName"][0] + return res[0]["dnsHostName"][0].decode('utf8') def get_domain_name(ctx): '''get netbios name of the domain from the partitions record''' partitions_dn = ctx.samdb.get_partitions_dn() res = ctx.samdb.search(base=partitions_dn, scope=ldb.SCOPE_ONELEVEL, attrs=["nETBIOSName"], expression='ncName=%s' % ldb.binary_encode(str(ctx.samdb.get_default_basedn()))) - return res[0]["nETBIOSName"][0] + return res[0]["nETBIOSName"][0].decode('utf8') def get_forest_domain_name(ctx): '''get netbios name of the domain from the partitions record''' partitions_dn = ctx.samdb.get_partitions_dn() res = ctx.samdb.search(base=partitions_dn, scope=ldb.SCOPE_ONELEVEL, attrs=["nETBIOSName"], expression='ncName=%s' % ldb.binary_encode(str(ctx.samdb.get_root_basedn()))) - return res[0]["nETBIOSName"][0] + return res[0]["nETBIOSName"][0].decode('utf8') def get_parent_partition_dn(ctx): '''get the parent domain partition DN from parent DNS name''' From 41f059ecb02352bd208ea2ea881e73272ba00fd6 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 17 Apr 2018 16:48:56 +0100 Subject: [PATCH 009/122] s4/selftest: Enable samba.tests.samba_tool.join for py3 --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 8f855344766..35596eb29db 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -591,7 +591,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.unix", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.srvsvc") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.timecmd", py3_compatible=True) -planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.join") +planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.join", py3_compatible=True) planpythontestsuite("none", "samba.tests.samba_tool.visualize") From 394120de508053454fd26be4470d11770b5603d2 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 18 Apr 2018 10:42:03 +0100 Subject: [PATCH 010/122] strings with utf content -> u (ensuring they are treated as unicode) --- python/samba/graph.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/python/samba/graph.py b/python/samba/graph.py index a36dc25c2f7..33cb0eb64da 100644 --- a/python/samba/graph.py +++ b/python/samba/graph.py @@ -204,8 +204,8 @@ def compile_graph_key(key_items, nodes_above=[], elisions=None, if short[0] == ',' and long[0] == ',': short = short[1:] long = long[1:] - elision_str += ('\nelision%d[shape=plaintext; style=solid; ' - 'label="\“%s” means “%s”\\r"]\n' + elision_str += (u'\nelision%d[shape=plaintext; style=solid; ' + u'label="\“%s” means “%s”\\r"]\n' % ((i, short, long))) above_lines = [] @@ -519,14 +519,14 @@ def distance_matrix(vertices, edges, write = lines.append if utf8: - vertical = '│' - horizontal = '─' - corner = '╭' + vertical = u'│' + horizontal = u'─' + corner = u'╭' #diagonal = '╲' - diagonal = '·' - #missing = '🕱' - missing = '-' - right_arrow = '←' + diagonal = u'·' + #missing = u'🕱' + missing = u'-' + right_arrow = u'←' else: vertical, horizontal, corner, diagonal, missing = '|-,0-' right_arrow = '<-' From e47dadb425ebe7777850f1e57b24e5f15f85a274 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 24 Apr 2018 09:23:02 +0100 Subject: [PATCH 011/122] python/samba/tests: prefix expected with 'u' as graph funcs return unicode --- python/samba/tests/graph.py | 60 ++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/python/samba/tests/graph.py b/python/samba/tests/graph.py index 7ea53caa734..38590e91e8d 100644 --- a/python/samba/tests/graph.py +++ b/python/samba/tests/graph.py @@ -124,7 +124,7 @@ def test_simple_distance(self): ('cat', 'dog')] expected = { - "utf8 True, colour None": ''' + "utf8 True, colour None": u''' destination ╭────── ant │╭───── bat @@ -138,7 +138,7 @@ def test_simple_distance(self): dog ---·-- elephant 2311·- frog 23121·''', - 'utf8 True, colour ansi': ''' + 'utf8 True, colour ansi': u''' destination ╭────── ant │╭───── bat @@ -153,7 +153,7 @@ def test_simple_distance(self): elephant 2311·-  frog 23121· ''', - 'utf8 True, colour ansi-heatmap': ''' + 'utf8 True, colour ansi-heatmap': u''' destination ╭────── ant │╭───── bat @@ -168,7 +168,7 @@ def test_simple_distance(self): elephant 2311·-  frog 23121· ''', - 'utf8 True, colour xterm-256color': ''' + 'utf8 True, colour xterm-256color': u''' destination ╭────── ant │╭───── bat @@ -183,7 +183,7 @@ def test_simple_distance(self): elephant 2311·-  frog 23121· ''', -'utf8 True, colour xterm-256color-heatmap': ''' +'utf8 True, colour xterm-256color-heatmap': u''' destination ╭────── ant │╭───── bat @@ -198,7 +198,7 @@ def test_simple_distance(self): elephant 2311·-  frog 23121· ''', -'utf8 False, colour None': ''' +'utf8 False, colour None': u''' destination ,------ ant |,----- bat @@ -213,7 +213,7 @@ def test_simple_distance(self): elephant 23110- frog 231210 ''', -'utf8 False, colour ansi': ''' +'utf8 False, colour ansi': u''' destination ,------ ant |,----- bat @@ -228,7 +228,7 @@ def test_simple_distance(self): elephant 23110-  frog 231210 ''', -'utf8 False, colour ansi-heatmap': ''' +'utf8 False, colour ansi-heatmap': u''' destination ,------ ant |,----- bat @@ -243,7 +243,7 @@ def test_simple_distance(self): elephant 23110-  frog 231210 ''', -'utf8 False, colour xterm-256color': ''' +'utf8 False, colour xterm-256color': u''' destination ,------ ant |,----- bat @@ -258,7 +258,7 @@ def test_simple_distance(self): elephant 23110-  frog 231210 ''', -'utf8 False, colour xterm-256color-heatmap': ''' +'utf8 False, colour xterm-256color-heatmap': u''' destination ,------ ant |,----- bat @@ -288,7 +288,7 @@ def test_simple_distance2(self): ('bat', 'ant'), ('ant', 'cat')] expected = { - 'utf8 True, colour None': ''' + 'utf8 True, colour None': u''' destination ╭─── ant │╭── bat @@ -297,7 +297,7 @@ def test_simple_distance2(self): bat 1·2 cat 21· ''', - 'utf8 True, colour ansi': ''' + 'utf8 True, colour ansi': u''' destination ╭─── ant │╭── bat @@ -306,7 +306,7 @@ def test_simple_distance2(self):  bat 1·2  cat 21· ''', -'utf8 True, colour ansi-heatmap': ''' +'utf8 True, colour ansi-heatmap': u''' destination ╭─── ant │╭── bat @@ -315,7 +315,7 @@ def test_simple_distance2(self):  bat 1·2  cat 21· ''', -'utf8 True, colour xterm-256color': ''' +'utf8 True, colour xterm-256color': u''' destination ╭─── ant │╭── bat @@ -324,7 +324,7 @@ def test_simple_distance2(self):  bat 1·2  cat 21· ''', -'utf8 True, colour xterm-256color-heatmap': ''' +'utf8 True, colour xterm-256color-heatmap': u''' destination ╭─── ant │╭── bat @@ -333,7 +333,7 @@ def test_simple_distance2(self):  bat 1·2  cat 21· ''', -'utf8 False, colour None': ''' +'utf8 False, colour None': u''' destination ,--- ant |,-- bat @@ -342,7 +342,7 @@ def test_simple_distance2(self): bat 102 cat 210 ''', -'utf8 False, colour ansi': ''' +'utf8 False, colour ansi': u''' destination ,--- ant |,-- bat @@ -351,7 +351,7 @@ def test_simple_distance2(self):  bat 102  cat 210 ''', -'utf8 False, colour ansi-heatmap': ''' +'utf8 False, colour ansi-heatmap': u''' destination ,--- ant |,-- bat @@ -360,7 +360,7 @@ def test_simple_distance2(self):  bat 102  cat 210 ''', -'utf8 False, colour xterm-256color': ''' +'utf8 False, colour xterm-256color': u''' destination ,--- ant |,-- bat @@ -369,7 +369,7 @@ def test_simple_distance2(self):  bat 102  cat 210 ''', -'utf8 False, colour xterm-256color-heatmap': ''' +'utf8 False, colour xterm-256color-heatmap': u''' destination ,--- ant |,-- bat @@ -394,7 +394,7 @@ def test_simple_distance3(self): ('dog', 'ant'), ('dog', 'eel')] expected = { -'utf8 True, colour None': ''' +'utf8 True, colour None': u''' destination ╭───── ant │╭──── bat @@ -407,7 +407,7 @@ def test_simple_distance3(self): dog 123·1 eel ----· ''', -'utf8 True, colour ansi': ''' +'utf8 True, colour ansi': u''' destination ╭───── ant │╭──── bat @@ -420,7 +420,7 @@ def test_simple_distance3(self):  dog 123·1  eel ----· ''', -'utf8 True, colour ansi-heatmap': ''' +'utf8 True, colour ansi-heatmap': u''' destination ╭───── ant │╭──── bat @@ -433,7 +433,7 @@ def test_simple_distance3(self):  dog 123·1  eel ----· ''', -'utf8 True, colour xterm-256color': ''' +'utf8 True, colour xterm-256color': u''' destination ╭───── ant │╭──── bat @@ -446,7 +446,7 @@ def test_simple_distance3(self):  dog 123·1  eel ----· ''', -'utf8 True, colour xterm-256color-heatmap': ''' +'utf8 True, colour xterm-256color-heatmap': u''' destination ╭───── ant │╭──── bat @@ -459,7 +459,7 @@ def test_simple_distance3(self):  dog 123·1  eel ----· ''', -'utf8 False, colour None': ''' +'utf8 False, colour None': u''' destination ,----- ant |,---- bat @@ -472,7 +472,7 @@ def test_simple_distance3(self): dog 12301 eel ----0 ''', -'utf8 False, colour ansi': ''' +'utf8 False, colour ansi': u''' destination ,----- ant |,---- bat @@ -485,7 +485,7 @@ def test_simple_distance3(self):  dog 12301  eel ----0 ''', -'utf8 False, colour ansi-heatmap': ''' +'utf8 False, colour ansi-heatmap': u''' destination ,----- ant |,---- bat @@ -499,7 +499,7 @@ def test_simple_distance3(self):  eel ----0 ''', 'utf8 False, colour xterm-256color': -''' destination +u''' destination ,----- ant |,---- bat ||,--- cat @@ -511,7 +511,7 @@ def test_simple_distance3(self):  dog 12301  eel ----0 ''', -'utf8 False, colour xterm-256color-heatmap': ''' +'utf8 False, colour xterm-256color-heatmap': u''' destination ,----- ant |,---- bat From 5d98ea59b1d49eafad19249a85e92db96f4a10b3 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 18 Apr 2018 12:33:51 +0100 Subject: [PATCH 012/122] targeted p3 port use io.open to be able to specifiy encoding for text we write specify utf8 in write (hmmm maybe we should just be doing this anyway regardless) #TODO check again --- python/samba/netcmd/visualize.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/python/samba/netcmd/visualize.py b/python/samba/netcmd/visualize.py index c9bc8244df6..0f1a60d3b9a 100644 --- a/python/samba/netcmd/visualize.py +++ b/python/samba/netcmd/visualize.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # Visualisation tools # # Copyright (C) Andrew Bartlett 2015, 2018 @@ -37,6 +38,7 @@ from samba.kcc import KCC, ldif_import_export from samba.kcc.kcc_utils import KCCError from samba.compat import text_type +from io import open COMMON_OPTIONS = [ Option("-H", "--URL", help="LDB URL for database or target server", @@ -99,7 +101,7 @@ def get_kcc_and_dsas(self, H, lp, creds): return kcc, dsas - def write(self, s, fn=None, suffix='.dot'): + def write(self, s, fn=None, suffix='.dot', utf8=None): """Decide whether we're dealing with a filename, a tempfile, or stdout, and write accordingly. @@ -111,18 +113,20 @@ def write(self, s, fn=None, suffix='.dot'): If fn is visualize.TEMP_FILE, write to a temporary file Otherwise fn should be a filename to write to. """ + encoding = None; + if utf8: + encoding = 'utf8'; if fn is None or fn == '-': # we're just using stdout (a.k.a self.outf) print(s, file=self.outf) return - if fn is TEMP_FILE: fd, fn = tempfile.mkstemp(prefix='samba-tool-visualise', suffix=suffix) - f = open(fn, 'w') + f = open(fn, 'w', encoding=encoding) os.close(fd) else: - f = open(fn, 'w') + f = open(fn, 'w', encoding=encoding) f.write(s) f.close() @@ -347,7 +351,7 @@ def run(self, H=None, output=None, shorten_names=False, grouping_function=get_dnstr_site) s = "\n%s\n%s" % (header_strings[direction] % part, s) - self.write(s, output) + self.write(s, output, utf8=utf8) return edge_colours = [] @@ -396,7 +400,7 @@ def run(self, H=None, output=None, shorten_names=False, if format == 'xdot': self.call_xdot(s, output) else: - self.write(s, output) + self.write(s, output, utf8=utf8) class NTDSConn(object): @@ -593,7 +597,7 @@ def run(self, H=None, output=None, shorten_names=False, self.write('\n%s\n\n%s\n%s' % (title, s, - epilog), output) + epilog), output, utf8=utf8) return dot_edges = [] @@ -654,7 +658,7 @@ def run(self, H=None, output=None, shorten_names=False, if format == 'xdot': self.call_xdot(s, output) else: - self.write(s, output) + self.write(s, output, utf8=utf8) class cmd_visualize(SuperCommand): From 002302d373a21965167a0ac36b88c29b89d02983 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 18 Apr 2018 16:51:21 +0100 Subject: [PATCH 013/122] make sure only unicode is written to 'write' --- python/samba/netcmd/visualize.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/samba/netcmd/visualize.py b/python/samba/netcmd/visualize.py index 0f1a60d3b9a..402024a75d8 100644 --- a/python/samba/netcmd/visualize.py +++ b/python/samba/netcmd/visualize.py @@ -127,7 +127,8 @@ def write(self, s, fn=None, suffix='.dot', utf8=None): os.close(fd) else: f = open(fn, 'w', encoding=encoding) - + if isinstance(s, str): + s = s.decode('utf8') f.write(s) f.close() return fn From ead22e3be0dea7aaae19ad7bad032259fe8408a7 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 18 Apr 2018 17:56:53 +0100 Subject: [PATCH 014/122] python/samba/tests: more tweaks to get samba.tests.visualize to run Note: this is NOT to get the visualize tests to run via py2/py3 but rather get the tests to run post some changes that change the result of some functions e.g. get_dsServiceName() & get_serverName() in python/samba/samdb.py which now return unicode strings which was needed to ensure py2/py3 compatability when running samba.tests.dsdb_lock under py2/py3 --- python/samba/tests/samba_tool/visualize.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/samba/tests/samba_tool/visualize.py b/python/samba/tests/samba_tool/visualize.py index abb6c49b3ad..128360f4b8e 100644 --- a/python/samba/tests/samba_tool/visualize.py +++ b/python/samba/tests/samba_tool/visualize.py @@ -262,7 +262,7 @@ def test_utf8(self): '-H', self.dburl, '--color=no', '-S') self.assertCmdSuccess(result, ascii, err) - for c in ('│', '─', '╭'): + for c in (u'│', u'─', u'╭'): self.assertTrue(c in utf8, 'UTF8 should contain %s' % c) self.assertTrue(c not in ascii, 'ASCII should not contain %s' % c) @@ -380,7 +380,7 @@ def test_dot_ntdsconn_disconnected(self): '-o', '-') self.assertCmdSuccess(result, dot, err) self.remove_files(dbfile) - self.assertStringsEqual(EXPECTED_DOT_NTDSCONN_DISCONNECTED, dot, + self.assertStringsEqual(EXPECTED_DOT_NTDSCONN_DISCONNECTED, dot.encode('utf8'), strip=True) def test_dot_ntdsconn_disconnected_to_file(self): From 211dc23020aff37c8c24669163997b500ce1d725 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 18 Apr 2018 19:44:23 +0100 Subject: [PATCH 015/122] tweak test and impl a little more to try and get it to run under py2 still py2 (but using unicode) --- python/samba/netcmd/visualize.py | 8 ++++---- python/samba/tests/samba_tool/visualize.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/python/samba/netcmd/visualize.py b/python/samba/netcmd/visualize.py index 402024a75d8..a700e3ffa99 100644 --- a/python/samba/netcmd/visualize.py +++ b/python/samba/netcmd/visualize.py @@ -113,9 +113,11 @@ def write(self, s, fn=None, suffix='.dot', utf8=None): If fn is visualize.TEMP_FILE, write to a temporary file Otherwise fn should be a filename to write to. """ - encoding = None; + encoding = None if utf8: - encoding = 'utf8'; + encoding = 'utf8' + if isinstance(s, str): + s = s.decode('utf8') if fn is None or fn == '-': # we're just using stdout (a.k.a self.outf) print(s, file=self.outf) @@ -127,8 +129,6 @@ def write(self, s, fn=None, suffix='.dot', utf8=None): os.close(fd) else: f = open(fn, 'w', encoding=encoding) - if isinstance(s, str): - s = s.decode('utf8') f.write(s) f.close() return fn diff --git a/python/samba/tests/samba_tool/visualize.py b/python/samba/tests/samba_tool/visualize.py index 128360f4b8e..7d229c6c7ec 100644 --- a/python/samba/tests/samba_tool/visualize.py +++ b/python/samba/tests/samba_tool/visualize.py @@ -399,7 +399,7 @@ def test_dot_ntdsconn_disconnected_to_file(self): f = open(dot_file) dot = f.read() f.close() - self.assertStringsEqual(EXPECTED_DOT_NTDSCONN_DISCONNECTED, dot) + self.assertStringsEqual(EXPECTED_DOT_NTDSCONN_DISCONNECTED, dot.encode('utf8')) self.remove_files(dbfile, dot_file) From 233c93ac03950c768a9cb780a5babb280fcd73fc Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 19 Apr 2018 16:05:14 +0100 Subject: [PATCH 016/122] python2 unicode support changes. Bit of a descrepency, it seems we write unicode when writing file but return when no output file or '-' is specified. Adjust test so that we don't use r"blah blah blah" raw string format as this will screw up when we use python3. python 2 dot type from file is unicode raw string is python3 dot type from file is raw string is This means for the test to pass running python2 we need to encode the return from the file (e.g. unicde) to convert to so we can compare. With python3 we can't do that (no encode method for ). We need the result and expected result types to match (in python2 & python3) --- python/samba/tests/samba_tool/visualize.py | 50 +++++++++++++++--------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/python/samba/tests/samba_tool/visualize.py b/python/samba/tests/samba_tool/visualize.py index 7d229c6c7ec..72703da039e 100644 --- a/python/samba/tests/samba_tool/visualize.py +++ b/python/samba/tests/samba_tool/visualize.py @@ -380,7 +380,7 @@ def test_dot_ntdsconn_disconnected(self): '-o', '-') self.assertCmdSuccess(result, dot, err) self.remove_files(dbfile) - self.assertStringsEqual(EXPECTED_DOT_NTDSCONN_DISCONNECTED, dot.encode('utf8'), + self.assertStringsEqual(EXPECTED_DOT_NTDSCONN_DISCONNECTED, dot, strip=True) def test_dot_ntdsconn_disconnected_to_file(self): @@ -399,7 +399,7 @@ def test_dot_ntdsconn_disconnected_to_file(self): f = open(dot_file) dot = f.read() f.close() - self.assertStringsEqual(EXPECTED_DOT_NTDSCONN_DISCONNECTED, dot.encode('utf8')) + self.assertStringsEqual(EXPECTED_DOT_NTDSCONN_DISCONNECTED, dot) self.remove_files(dbfile, dot_file) @@ -443,25 +443,25 @@ def test_dot_ntdsconn_disconnected_to_file(self): """ -EXPECTED_DOT_NTDSCONN_DISCONNECTED = r"""/* generated by samba */ +EXPECTED_DOT_NTDSCONN_DISCONNECTED = u"""/* generated by samba */ digraph A_samba_tool_production { label="NTDS Connections known to CN=LOCALDC,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=samba,DC=example,DC=com"; fontsize=10; node[fontname=Helvetica; fontsize=10]; -"CN=NTDS Settings,\nCN=CLIENT,\n..."; -"CN=NTDS Settings,\nCN=LOCALDC,\n..."; -"CN=NTDS Settings,\nCN=PROMOTEDVDC,\n..."; -"CN=NTDS Settings,\nCN=SERVER1,\n..."; -"CN=NTDS Settings,\nCN=SERVER2,\n..."; -"CN=NTDS Settings,\nCN=SERVER3,\n..."; -"CN=NTDS Settings,\nCN=SERVER4,\n..."; -"CN=NTDS Settings,\nCN=SERVER5,\n..."; -"CN=NTDS Settings,\nCN=LOCALDC,\n..." -> "CN=NTDS Settings,\nCN=PROMOTEDVDC,\n..." [color="#000000", ]; -"CN=NTDS Settings,\nCN=PROMOTEDVDC,\n..." -> "CN=NTDS Settings,\nCN=LOCALDC,\n..." [color="#000000", ]; -"CN=NTDS Settings,\nCN=SERVER2,\n..." -> "CN=NTDS Settings,\nCN=PROMOTEDVDC,\n..." [color="#000000", ]; -"CN=NTDS Settings,\nCN=SERVER3,\n..." -> "CN=NTDS Settings,\nCN=LOCALDC,\n..." [color="#000000", ]; +"CN=NTDS Settings,\\nCN=CLIENT,\\n..."; +"CN=NTDS Settings,\\nCN=LOCALDC,\\n..."; +"CN=NTDS Settings,\\nCN=PROMOTEDVDC,\\n..."; +"CN=NTDS Settings,\\nCN=SERVER1,\\n..."; +"CN=NTDS Settings,\\nCN=SERVER2,\\n..."; +"CN=NTDS Settings,\\nCN=SERVER3,\\n..."; +"CN=NTDS Settings,\\nCN=SERVER4,\\n..."; +"CN=NTDS Settings,\\nCN=SERVER5,\\n..."; +"CN=NTDS Settings,\\nCN=LOCALDC,\\n..." -> "CN=NTDS Settings,\\nCN=PROMOTEDVDC,\\n..." [color="#000000", ]; +"CN=NTDS Settings,\\nCN=PROMOTEDVDC,\\n..." -> "CN=NTDS Settings,\\nCN=LOCALDC,\\n..." [color="#000000", ]; +"CN=NTDS Settings,\\nCN=SERVER2,\\n..." -> "CN=NTDS Settings,\\nCN=PROMOTEDVDC,\\n..." [color="#000000", ]; +"CN=NTDS Settings,\\nCN=SERVER3,\\n..." -> "CN=NTDS Settings,\\nCN=LOCALDC,\\n..." [color="#000000", ]; subgraph cluster_key { label="Key"; subgraph cluster_key_nodes { @@ -476,22 +476,22 @@ def test_dot_ntdsconn_disconnected_to_file(self): key_0_e1[label=src; color="#000000"; group="key_0__g"] key_0_e2[label=dest; color="#000000"; group="key_0__g"] key_0_e1 -> key_0_e2 [constraint = false; color="#000000"] -key_0__label[shape=plaintext; style=solid; width=2.000000; label="NTDS Connection\r"] +key_0__label[shape=plaintext; style=solid; width=2.000000; label="NTDS Connection\\r"] } {key_0__label} } -elision0[shape=plaintext; style=solid; label="\“...” means “CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=samba,DC=example,DC=com”\r"] +elision0[shape=plaintext; style=solid; label="\\“...” means “CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=samba,DC=example,DC=com”\\r"] } -"CN=NTDS Settings,\nCN=CLIENT,\n..." -> key_0__label [style=invis]; -"CN=NTDS Settings,\nCN=LOCALDC,\n..." -> key_0__label [style=invis]; -"CN=NTDS Settings,\nCN=PROMOTEDVDC,\n..." -> key_0__label [style=invis]; -"CN=NTDS Settings,\nCN=SERVER1,\n..." -> key_0__label [style=invis]; -"CN=NTDS Settings,\nCN=SERVER2,\n..." -> key_0__label [style=invis]; -"CN=NTDS Settings,\nCN=SERVER3,\n..." -> key_0__label [style=invis]; -"CN=NTDS Settings,\nCN=SERVER4,\n..." -> key_0__label [style=invis]; -"CN=NTDS Settings,\nCN=SERVER5,\n..." -> key_0__label [style=invis] +"CN=NTDS Settings,\\nCN=CLIENT,\\n..." -> key_0__label [style=invis]; +"CN=NTDS Settings,\\nCN=LOCALDC,\\n..." -> key_0__label [style=invis]; +"CN=NTDS Settings,\\nCN=PROMOTEDVDC,\\n..." -> key_0__label [style=invis]; +"CN=NTDS Settings,\\nCN=SERVER1,\\n..." -> key_0__label [style=invis]; +"CN=NTDS Settings,\\nCN=SERVER2,\\n..." -> key_0__label [style=invis]; +"CN=NTDS Settings,\\nCN=SERVER3,\\n..." -> key_0__label [style=invis]; +"CN=NTDS Settings,\\nCN=SERVER4,\\n..." -> key_0__label [style=invis]; +"CN=NTDS Settings,\\nCN=SERVER5,\\n..." -> key_0__label [style=invis] key_0__label -> elision0 [style=invis; weight=9] } From a464ff4a4eb2d8efb5d43680c0490c33f79cf63a Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 19 Apr 2018 16:15:58 +0100 Subject: [PATCH 017/122] python3: Ensure some attributes are coverted to string before use. --- python/samba/kcc/kcc_utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/samba/kcc/kcc_utils.py b/python/samba/kcc/kcc_utils.py index 1457ea355e0..6ebcef84509 100644 --- a/python/samba/kcc/kcc_utils.py +++ b/python/samba/kcc/kcc_utils.py @@ -993,7 +993,7 @@ def load_connection(self, samdb): self.schedule = ndr_unpack(drsblobs.schedule, msg["schedule"][0]) if "whenCreated" in msg: - self.whenCreated = ldb.string_to_time(msg["whenCreated"][0]) + self.whenCreated = ldb.string_to_time(msg["whenCreated"][0].decode('utf8')) if "fromServer" in msg: dsdn = dsdb_Dn(samdb, msg["fromServer"][0].decode('utf8')) @@ -1919,10 +1919,10 @@ def load_transport(self, samdb): self.options = int(msg["options"][0]) if "transportAddressAttribute" in msg: - self.address_attr = str(msg["transportAddressAttribute"][0]) + self.address_attr = msg["transportAddressAttribute"][0].decode('utf8') if "name" in msg: - self.name = str(msg["name"][0]) + self.name = msg["name"][0].decode('utf8') if "bridgeheadServerListBL" in msg: for value in msg["bridgeheadServerListBL"]: From 52a0ac95f5a696888c5b607aee1769d548e04536 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 19 Apr 2018 16:17:02 +0100 Subject: [PATCH 018/122] python3: couple of changes to ensure visualize works with py2/py3 * make sure a bytes attribute is converted to string * make sure we handles a bytes in py3 or str in py2 and convert to str and unicode respectively --- python/samba/netcmd/visualize.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/samba/netcmd/visualize.py b/python/samba/netcmd/visualize.py index a700e3ffa99..56f9e19495f 100644 --- a/python/samba/netcmd/visualize.py +++ b/python/samba/netcmd/visualize.py @@ -116,7 +116,7 @@ def write(self, s, fn=None, suffix='.dot', utf8=None): encoding = None if utf8: encoding = 'utf8' - if isinstance(s, str): + if not isinstance(s, text_type): s = s.decode('utf8') if fn is None or fn == '-': # we're just using stdout (a.k.a self.outf) @@ -495,7 +495,7 @@ def run(self, H=None, output=None, shorten_names=False, for msg in res: msgdn = str(msg.dn) dest_dn = msgdn[msgdn.index(',') + 1:] - attested_edges.append((msg['fromServer'][0], + attested_edges.append((msg['fromServer'][0].decode('utf8'), dest_dn, ntds_dn)) if importldif and H == self._tmp_fn_to_delete: From ac44a8984ceb192812e7d633263026f194d0c162 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 20 Apr 2018 16:34:17 +0100 Subject: [PATCH 019/122] python2/python3 compat tweaks --- python/samba/netcmd/visualize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samba/netcmd/visualize.py b/python/samba/netcmd/visualize.py index 56f9e19495f..12a38e2c79e 100644 --- a/python/samba/netcmd/visualize.py +++ b/python/samba/netcmd/visualize.py @@ -459,7 +459,7 @@ def run(self, H=None, output=None, shorten_names=False, res = local_kcc.samdb.search(dsa_dn, scope=SCOPE_BASE, attrs=["dNSHostName"]) - dns_name = res[0]["dNSHostName"][0] + dns_name = res[0]["dNSHostName"][0].decode('utf8') try: samdb = self.get_db("ldap://%s" % dns_name, sambaopts, credopts) From 04e2f9d8623bc6e6c12157070d9ea8666d6e12d1 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 24 Apr 2018 20:34:38 +0100 Subject: [PATCH 020/122] python/samba/tests/samba_tool: fix a native string containing some non ascii "HIGH\xFFBYTE" is a string containing such text. In python2 we seem to get some problems when intermixing 'str' (e.g. bytes) with proper unicode. Note: some of the py2/py3 changes have peppered unicode around the place (where it wasn't before). --- python/samba/tests/samba_tool/dnscmd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samba/tests/samba_tool/dnscmd.py b/python/samba/tests/samba_tool/dnscmd.py index c44a3083716..2c3ced7d03c 100644 --- a/python/samba/tests/samba_tool/dnscmd.py +++ b/python/samba/tests/samba_tool/dnscmd.py @@ -48,7 +48,7 @@ def setUp(self): "EXAMPLE", "\n.COM", "!@#$%^&*()_", - "HIGH\xFFBYTE", + u"HIGH\xFFBYTE", "@.EXAMPLE.COM", "."] bad_dns = ["...", From a06eb04db0c0ca988b325cd21f4afacff278812e Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 20 Apr 2018 17:24:44 +0100 Subject: [PATCH 021/122] enable samba_tool.visualize_drs samba_tool.visualize_drs for py3 --- source4/selftest/tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 35596eb29db..38c796ba00b 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -593,7 +593,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.timecmd", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.join", py3_compatible=True) -planpythontestsuite("none", "samba.tests.samba_tool.visualize") +planpythontestsuite("none", "samba.tests.samba_tool.visualize", py3_compatible=True) # test fsmo show @@ -1037,7 +1037,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex }, extra_path=[os.path.join(srcdir(), "samba/python"), ] ) - planpythontestsuite(env, "samba.tests.samba_tool.visualize_drs") + planpythontestsuite(env, "samba.tests.samba_tool.visualize_drs", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.kcc.kcc_utils") From 65f36eeff23c6a900202c9e94abe7bfc507225d8 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 20 Apr 2018 17:42:41 +0100 Subject: [PATCH 022/122] enable samba.tests.dcerpc.srvsvc (even though it seemsnot run (dangerous test) --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 38c796ba00b..085a1c360fd 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -589,7 +589,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planpythontestsuite("none", "samba.tests.dsdb_lock", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.bare", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.unix", py3_compatible=True) -planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.srvsvc") +planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.srvsvc", py3_compatible=False) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.timecmd", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.join", py3_compatible=True) From 843ec85bfd4a8e0816fdc5aeee10676cb3c07b00 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 23 Apr 2018 12:21:31 +0100 Subject: [PATCH 023/122] python/samba/tests: Port fsmo test to python3 --- python/samba/tests/samba_tool/fsmo.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/samba/tests/samba_tool/fsmo.py b/python/samba/tests/samba_tool/fsmo.py index 7fd0ae2e033..847239d862d 100644 --- a/python/samba/tests/samba_tool/fsmo.py +++ b/python/samba/tests/samba_tool/fsmo.py @@ -36,7 +36,7 @@ def test_fsmoget(self): res = samdb.search(base=ldb.Dn(samdb, "CN=Infrastructure,DC=DomainDnsZones") + samdb.get_default_basedn(), scope=ldb.SCOPE_BASE, attrs=["fsmoRoleOwner"]) - self.assertTrue("DomainDnsZonesMasterRole owner: " + res[0]["fsmoRoleOwner"][0] in out) + self.assertTrue("DomainDnsZonesMasterRole owner: " + res[0]["fsmoRoleOwner"][0].decode('utf8') in out) except ldb.LdbError as e: (enum, string) = e.args if enum == ldb.ERR_NO_SUCH_OBJECT: @@ -47,4 +47,4 @@ def test_fsmoget(self): res = samdb.search(base=samdb.get_default_basedn(), scope=ldb.SCOPE_BASE, attrs=["fsmoRoleOwner"]) - self.assertTrue("DomainNamingMasterRole owner: " + res[0]["fsmoRoleOwner"][0] in out) + self.assertTrue("DomainNamingMasterRole owner: " + res[0]["fsmoRoleOwner"][0].decode('utf8') in out) From c37618825b8c182cc91e49b9c3abd48e57d1b2ed Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 23 Apr 2018 12:21:53 +0100 Subject: [PATCH 024/122] s3/selftest: Enable samba.tests.samba_tool.fsmo for python3 --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 085a1c360fd..70d4033f30d 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -598,7 +598,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex # test fsmo show for env in ["ad_dc_ntvfs", "fl2000dc", "fl2003dc", "fl2008r2dc"]: - planpythontestsuite(env + ":local", "samba.tests.samba_tool.fsmo") + planpythontestsuite(env + ":local", "samba.tests.samba_tool.fsmo", py3_compatible=True) # test user.edit for env in ["ad_dc:local", "ad_dc_ntvfs:local", "fl2000dc:local", "fl2003dc:local", "fl2008r2dc:local"]: From 7fa80152f255fb71d7a30745dae597e49303f1e0 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 23 Apr 2018 14:01:01 +0100 Subject: [PATCH 025/122] python/samba/netcmd: some changes to be python2/python3 compatable --- python/samba/netcmd/gpo.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/samba/netcmd/gpo.py b/python/samba/netcmd/gpo.py index 42562728791..43907d10ddd 100644 --- a/python/samba/netcmd/gpo.py +++ b/python/samba/netcmd/gpo.py @@ -256,7 +256,7 @@ def copy_directory_remote_to_local(conn, remotedir, localdir): os.mkdir(l_name) else: data = conn.loadfile(r_name) - open(l_name, 'w').write(data) + open(l_name, 'wb').write(data) def copy_directory_local_to_remote(conn, localdir, remotedir): @@ -278,7 +278,7 @@ def copy_directory_local_to_remote(conn, localdir, remotedir): r_dirs.append(r_name) conn.mkdir(r_name) else: - data = open(l_name, 'r').read() + data = open(l_name, 'rb').read() conn.savefile(r_name, data) @@ -839,7 +839,7 @@ def run(self, gpo, H=None, tmpdir=None, sambaopts=None, credopts=None, versionop raise CommandError("GPO '%s' does not exist" % gpo) # verify UNC path - unc = msg['gPCFileSysPath'][0] + unc = msg['gPCFileSysPath'][0].decode('utf8') try: [dom_name, service, sharepath] = parse_unc(unc) except ValueError: @@ -1060,7 +1060,7 @@ def run(self, gpo, H=None, sambaopts=None, credopts=None, # Check if valid GPO try: msg = get_gpo_info(self.samdb, gpo=gpo)[0] - unc_path = msg['gPCFileSysPath'][0] + unc_path = msg['gPCFileSysPath'][0].decode('utf8') except Exception: raise CommandError("GPO '%s' does not exist" % gpo) @@ -1137,7 +1137,7 @@ def run(self, H=None, sambaopts=None, credopts=None, versionopts=None): for m in msg: # verify UNC path - unc = m['gPCFileSysPath'][0] + unc = m['gPCFileSysPath'][0].decode('utf8') try: [dom_name, service, sharepath] = parse_unc(unc) except ValueError: From 2202c05ce35318a1aa56022801a77294341639d0 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 23 Apr 2018 14:01:44 +0100 Subject: [PATCH 026/122] s4/selftest: enable samba.tests.samba_tool.gpo for python3 --- source4/selftest/tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 70d4033f30d..6b2efee9009 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -607,8 +607,8 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex # We run this test against both AD DC implemetnations because it is # the only test we have of GPO get/set behaviour, and this involves # the file server as well as the LDAP server. -planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.gpo") -planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.gpo") +planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.gpo", py3_compatible=True) +planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.gpo",py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.processes") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.user") From f9b4aad01bc1afb4c557f2f79bda284790b0eb49 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 23 Apr 2018 14:03:13 +0100 Subject: [PATCH 027/122] s4/selftest: enable samba.tests.samba_tool.gpo for python3 --- source4/selftest/tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 6b2efee9009..99d04992826 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -607,8 +607,8 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex # We run this test against both AD DC implemetnations because it is # the only test we have of GPO get/set behaviour, and this involves # the file server as well as the LDAP server. -planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.gpo", py3_compatible=True) -planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.gpo",py3_compatible=True) +planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.gpo", py3_compatible=True) +planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.gpo", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.processes") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.user") From fba99f98ab0ee3737db511aa1734e13f67dc49a2 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 23 Apr 2018 14:07:05 +0100 Subject: [PATCH 028/122] s4/selftest: enable samba.tests.samba_tool.processes for python3 --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 99d04992826..c1bdc9c932b 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -610,7 +610,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.gpo", py3_compatible=True) planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.gpo", py3_compatible=True) -planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.processes") +planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.processes", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.user") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.user_wdigest") planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.user") From e8728b1550a46adc7a8ae00c5044cac1dd0005eb Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 23 Apr 2018 18:21:05 +0100 Subject: [PATCH 029/122] python/samba/tests: samba.tests.samba_tool.user_wdigest py2/py3 compat --- python/samba/netcmd/user.py | 5 ++++- python/samba/tests/samba_tool/user_wdigest.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/python/samba/netcmd/user.py b/python/samba/netcmd/user.py index f211b5158ce..45a76b545d4 100644 --- a/python/samba/netcmd/user.py +++ b/python/samba/netcmd/user.py @@ -383,6 +383,7 @@ def run(self, username, password=None, credopts=None, sambaopts=None, self.outf.write("User '%s' created successfully\n" % username) +from samba.compat import string_types class cmd_user_add(cmd_user_create): __doc__ = cmd_user_create.__doc__ @@ -977,7 +978,7 @@ def get_account_attributes(self, samdb, username, basedn, filter, scope, unicodePwd = obj["unicodePwd"][0] if add_unicodePwd: del obj["unicodePwd"] - account_name = obj["sAMAccountName"][0] + account_name = obj["sAMAccountName"][0].decode('utf8') if add_sAMAcountName: del obj["sAMAccountName"] if "userPrincipalName" in obj: @@ -1159,6 +1160,8 @@ def get_wDigest(i, primary_wdigest, account_name, account_upn, primary_wdigest) try: digest = binascii.hexlify(bytearray(digests.hashes[i-1].hash)) + if not isinstance(digest, string_types): + digest = digest.decode('utf8') return "%s:%s:%s" % (user, realm, digest) except IndexError: return None diff --git a/python/samba/tests/samba_tool/user_wdigest.py b/python/samba/tests/samba_tool/user_wdigest.py index eddb79f4d18..8a6ab0704e9 100644 --- a/python/samba/tests/samba_tool/user_wdigest.py +++ b/python/samba/tests/samba_tool/user_wdigest.py @@ -74,7 +74,7 @@ def setUp(self): base=self.samdb.get_config_basedn(), expression="ncName=%s" % self.samdb.get_default_basedn(), attrs=["nETBIOSName"]) - self.netbios_domain = res[0]["nETBIOSName"][0] + self.netbios_domain = res[0]["nETBIOSName"][0].decode('utf8') self.runsubcmd("user", "create", USER_NAME, From 24b3aa499cf340650a9cca436f211d52149e5072 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 23 Apr 2018 18:22:08 +0100 Subject: [PATCH 030/122] s4/selftest: enable samba.tests.samba_tool.user_wdigest for python3 --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index c1bdc9c932b..4724c149a6a 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -612,7 +612,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.processes", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.user") -planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.user_wdigest") +planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.user_wdigest", py3_compatible=True) planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.user") planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.user_virtualCryptSHA") planpythontestsuite("chgdcpass:local", "samba.tests.samba_tool.user_check_password_script") From 8db97ce3ce0d4d23f41f525f536a0954982e175b Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 24 Apr 2018 16:55:49 +0100 Subject: [PATCH 031/122] s4/selftest: enable samba.tests.samba_tool.user_check_password_script py3 --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 4724c149a6a..613cd40fa0a 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -615,7 +615,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.user_wdigest", py3_compatible=True) planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.user") planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.user_virtualCryptSHA") -planpythontestsuite("chgdcpass:local", "samba.tests.samba_tool.user_check_password_script") +planpythontestsuite("chgdcpass:local", "samba.tests.samba_tool.user_check_password_script", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.group") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.ou") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.computer") From d4fe646a4108e194c55622ea84ccb7c8f31b7713 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 24 Apr 2018 19:07:55 +0100 Subject: [PATCH 032/122] python/samba/netcmd: fix samba.test.group for py3 --- python/samba/netcmd/group.py | 4 ++-- python/samba/tests/samba_tool/group.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/python/samba/netcmd/group.py b/python/samba/netcmd/group.py index 9e1e11071f4..828d77b7e78 100644 --- a/python/samba/netcmd/group.py +++ b/python/samba/netcmd/group.py @@ -357,7 +357,7 @@ def run(self, sambaopts=None, credopts=None, versionopts=None, H=None, self.outf.write("\n") else: for msg in res: - self.outf.write("%s\n" % msg.get("samaccountname", idx=0)) + self.outf.write("%s\n" % msg.get("samaccountname", idx=0).decode('utf8')) class cmd_group_list_members(Command): """List all members of an AD group. @@ -417,7 +417,7 @@ def run(self, groupname, credopts=None, sambaopts=None, versionopts=None, H=None member_name = msg.get("samAccountName", idx=0) if member_name is None: member_name = msg.get("cn", idx=0) - self.outf.write("%s\n" % member_name) + self.outf.write("%s\n" % member_name.decode('utf8')) except Exception as e: raise CommandError('Failed to list members of "%s" group ' % groupname, e) diff --git a/python/samba/tests/samba_tool/group.py b/python/samba/tests/samba_tool/group.py index 06226717ab1..dd546085363 100644 --- a/python/samba/tests/samba_tool/group.py +++ b/python/samba/tests/samba_tool/group.py @@ -114,7 +114,7 @@ def test_list(self): self.assertTrue(len(grouplist) > 0, "no groups found in samdb") for groupobj in grouplist: - name = groupobj.get("samaccountname", idx=0) + name = groupobj.get("samaccountname", idx=0).decode('utf8') found = self.assertMatch(out, name, "group '%s' not found" % name) @@ -135,7 +135,7 @@ def test_listmembers(self): self.assertTrue(len(grouplist) > 0, "no groups found in samdb") for groupobj in grouplist: - name = groupobj.get("samAccountName", idx=0) + name = groupobj.get("samAccountName", idx=0).decode('utf8') found = self.assertMatch(out, name, "group '%s' not found" % name) def test_move(self): From ee32138f8ea23edcbbad3e1cb2264de82ee3de92 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 24 Apr 2018 19:08:27 +0100 Subject: [PATCH 033/122] s4/selftest: enable samba.tests.group for py3 --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 613cd40fa0a..7ff8689d055 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -616,7 +616,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.user") planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.user_virtualCryptSHA") planpythontestsuite("chgdcpass:local", "samba.tests.samba_tool.user_check_password_script", py3_compatible=True) -planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.group") +planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.group", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.ou") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.computer") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.forest") From 3246b198f2fe4095333ff3b13faba81ef8abc38a Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 26 Apr 2018 15:47:19 +0100 Subject: [PATCH 034/122] s4/selftest: enable samba.tests.samba_tool.ou for py3 --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 7ff8689d055..a01f7082041 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -617,7 +617,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.user_virtualCryptSHA") planpythontestsuite("chgdcpass:local", "samba.tests.samba_tool.user_check_password_script", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.group", py3_compatible=True) -planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.ou") +planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.ou", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.computer") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.forest") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.schema") From 28ee6ad5c96182a3bcf2331fd3d2f8dc39cda88e Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 26 Apr 2018 18:22:21 +0100 Subject: [PATCH 035/122] python/samba/netcmd: changes for samab.tests.samba_tool.computer --- python/samba/netcmd/computer.py | 4 ++-- python/samba/remove_dc.py | 2 +- python/samba/samdb.py | 2 +- python/samba/tests/samba_tool/computer.py | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/python/samba/netcmd/computer.py b/python/samba/netcmd/computer.py index 7a913b4fb3f..77e79f74528 100644 --- a/python/samba/netcmd/computer.py +++ b/python/samba/netcmd/computer.py @@ -281,7 +281,7 @@ def run(self, computername, credopts=None, sambaopts=None, versionopts=None, expression=filters, attrs=['primaryGroupID', 'objectSid']) - group = recs[0]['primaryGroupID'][0] + group = recs[0]['primaryGroupID'][0].decode('utf8') owner = ndr_unpack(security.dom_sid, recs[0]["objectSid"][0]) dns_conn = dnsserver.dnsserver( @@ -376,7 +376,7 @@ def run(self, computername, credopts=None, sambaopts=None, computer_dn = res[0].dn computer_ac = int(res[0]["userAccountControl"][0]) if "dNSHostName" in res[0]: - computer_dns_host_name = res[0]["dNSHostName"][0] + computer_dns_host_name = res[0]["dNSHostName"][0].decode('utf8') else: computer_dns_host_name = None except IndexError: diff --git a/python/samba/remove_dc.py b/python/samba/remove_dc.py index b9726f5b84f..7cff234c61e 100644 --- a/python/samba/remove_dc.py +++ b/python/samba/remove_dc.py @@ -135,7 +135,7 @@ def dns_name_from_dn(dn): # By using a set here, duplicates via (eg) example.com/Configuration # do not matter, they become just example.com a_names_to_remove_from \ - = set(dns_name_from_dn(dn) for dn in ncs) + = set(dns_name_from_dn(dn.decode('utf8')) for dn in ncs) def a_rec_to_remove(dnsRecord): if dnsRecord.wType == DNS_TYPE_A or dnsRecord.wType == DNS_TYPE_AAAA: diff --git a/python/samba/samdb.py b/python/samba/samdb.py index d4e1272bddc..cd978fff4f7 100644 --- a/python/samba/samdb.py +++ b/python/samba/samdb.py @@ -741,7 +741,7 @@ def server_site_name(self): def host_dns_name(self): """return the DNS name of this host""" res = self.search(base='', scope=ldb.SCOPE_BASE, attrs=['dNSHostName']) - return res[0]['dNSHostName'][0] + return res[0]['dNSHostName'][0].decode('utf8') def domain_dns_name(self): """return the DNS name of the domain root""" diff --git a/python/samba/tests/samba_tool/computer.py b/python/samba/tests/samba_tool/computer.py index 4036d973c12..52583601613 100644 --- a/python/samba/tests/samba_tool/computer.py +++ b/python/samba/tests/samba_tool/computer.py @@ -186,7 +186,7 @@ def test_list(self): self.assertTrue(len(computerlist) > 0, "no computers found in samdb") for computerobj in computerlist: - name = computerobj.get("samaccountname", idx=0) + name = computerobj.get("samaccountname", idx=0).decode('utf8') found = self.assertMatch(out, name, "computer '%s' not found" % name) @@ -265,7 +265,7 @@ def _create_computer(self, computer): args += ' --service-principal-name={}'.format(service_principal_name) args = args.split() - + print ('#### args %s %s' % (type(args), args)) return self.runsubcmd('computer', 'create', *args) def _create_ou(self, ou): @@ -325,5 +325,5 @@ def _find_service_principal_name(self, name, expected_service_principal_names): names = set() for computer in computer_list: for name in computer.get('servicePrincipalName', []): - names.add(name) + names.add(name.decode('utf8')) return names == set(expected_service_principal_names) From 611be4f4e2bfe7d020201cc1f10b3ae40f0ac645 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 26 Apr 2018 18:23:50 +0100 Subject: [PATCH 036/122] s4/selftest/tests: Enabled samba.tests.samba_tool.computer --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index a01f7082041..17823de69e1 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -618,7 +618,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planpythontestsuite("chgdcpass:local", "samba.tests.samba_tool.user_check_password_script", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.group", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.ou", py3_compatible=True) -planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.computer") +planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.computer", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.forest") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.schema") planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.ntacl") From 1bc769e90bc92007bd919f3d15786261a944ad7d Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 27 Apr 2018 13:02:50 +0100 Subject: [PATCH 037/122] python/samba/provision: remove use of str() func for binary data Python 2 code works with str(policy["nTSecurityDescriptor"]) however this cannot work with Python 3. One could argue even the str method doesn't make sense at all (returning a string) for data. Signed-off-by: Noel Power --- python/samba/provision/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/samba/provision/__init__.py b/python/samba/provision/__init__.py index 7fa039d0316..86be27f64a4 100644 --- a/python/samba/provision/__init__.py +++ b/python/samba/provision/__init__.py @@ -1606,7 +1606,7 @@ def set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, use_ntvfs, p for policy in res: acl = ndr_unpack(security.descriptor, - str(policy["nTSecurityDescriptor"])).as_sddl() + policy["nTSecurityDescriptor"][0]).as_sddl() policy_path = getpolicypath(sysvol, dnsdomain, str(policy["cn"])) set_dir_acl(policy_path, dsacl2fsacl(acl, domainsid), lp, str(domainsid), use_ntvfs, @@ -1767,7 +1767,7 @@ def check_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, for policy in res: acl = ndr_unpack(security.descriptor, - str(policy["nTSecurityDescriptor"])).as_sddl() + policy["nTSecurityDescriptor"][0]).as_sddl() policy_path = getpolicypath(sysvol, dnsdomain, str(policy["cn"])) check_dir_acl(policy_path, dsacl2fsacl(acl, domainsid), lp, domainsid, direct_db_access) From a4ac7ed355fbd16c9233ac42a6992869fd2c827d Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 27 Apr 2018 13:05:15 +0100 Subject: [PATCH 038/122] s4/selftest: enable samba.tests.samba_tool.ntacl for Py3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 17823de69e1..f007635e276 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -621,7 +621,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.computer", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.forest") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.schema") -planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.ntacl") +planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.ntacl", py3_compatible=True) planpythontestsuite("none", "samba.tests.samba_tool.provision_password_check") planpythontestsuite("none", "samba.tests.samba_tool.help") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.passwordsettings") From 56c8eb9443b2a1b73e2855c6b5665c63a1616319 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 27 Apr 2018 15:11:54 +0100 Subject: [PATCH 039/122] python/samba/netcmd: Fix password usage for py2/py3 compatability getpass returns str (e.g. bytes) in python2 and str (unicode) in py3. Adapt code to so we don't do illegal things (like try and decode) a string in python3 Signed-off-by: Noel Power --- python/samba/netcmd/domain.py | 7 +++++-- python/samba/provision/__init__.py | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/python/samba/netcmd/domain.py b/python/samba/netcmd/domain.py index 5438537ab1d..7142871c5c8 100644 --- a/python/samba/netcmd/domain.py +++ b/python/samba/netcmd/domain.py @@ -101,6 +101,8 @@ from samba.netcmd.pso import cmd_domain_passwordsettings_pso +from samba.compat import binary_type + string_version_to_constant = { "2008_R2" : DS_DOMAIN_FUNCTION_2008_R2, "2012": DS_DOMAIN_FUNCTION_2012, @@ -567,8 +569,9 @@ def _get_nameserver_ip(self): def _adminpass_issue(self, adminpass): """Returns error string for a bad administrator password, or None if acceptable""" - - if len(adminpass.decode('utf-8')) < DEFAULT_MIN_PWD_LENGTH: + if isinstance(adminpass, binary_type): + adminpass = adminpass.decode('utf8') + if len(adminpass) < DEFAULT_MIN_PWD_LENGTH: return "Administrator password does not meet the default minimum" \ " password length requirement (%d characters)" \ % DEFAULT_MIN_PWD_LENGTH diff --git a/python/samba/provision/__init__.py b/python/samba/provision/__init__.py index 86be27f64a4..be792350f17 100644 --- a/python/samba/provision/__init__.py +++ b/python/samba/provision/__init__.py @@ -28,6 +28,7 @@ from samba.compat import urllib_quote from samba.compat import string_types +from samba.compat import binary_type from base64 import b64encode import errno import os @@ -2275,7 +2276,8 @@ def provision(logger, session_info, smbconf=None, adminpass = samba.generate_random_password(12, 32) adminpass_generated = True else: - adminpass = unicode(adminpass, 'utf-8') + if isinstance(adminpass, binary_type): + adminpass = adminpass.decode('utf-8') adminpass_generated = False if samdb_fill == FILL_FULL: From 7b48e7f7bc046a36b76f33bcecb969af93ebb4f0 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 27 Apr 2018 15:13:49 +0100 Subject: [PATCH 040/122] s4/selftest: Enable samba.tests.samba_tool.provision_password_check for py3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index f007635e276..3b4c6b6902e 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -622,7 +622,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.forest") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.schema") planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.ntacl", py3_compatible=True) -planpythontestsuite("none", "samba.tests.samba_tool.provision_password_check") +planpythontestsuite("none", "samba.tests.samba_tool.provision_password_check", py3_compatible=True) planpythontestsuite("none", "samba.tests.samba_tool.help") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.passwordsettings") From 5e20254a1407484eebb1748f53aab13247518de4 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 27 Apr 2018 15:45:49 +0100 Subject: [PATCH 041/122] python/samba/tests: Py2/Py2 ensure bytes output is converted to text type Tests in python3 are intermingling bytes and strings types. Adjust code to ensure bytes are converted to str as appropriate --- python/samba/tests/samba_tool/help.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/python/samba/tests/samba_tool/help.py b/python/samba/tests/samba_tool/help.py index 62e0b3eaa23..853602c053c 100644 --- a/python/samba/tests/samba_tool/help.py +++ b/python/samba/tests/samba_tool/help.py @@ -20,7 +20,7 @@ import re from samba.tests.samba_tool.base import SambaToolCmdTest from samba.tests import BlackboxProcessError - +from samba.compat import binary_type class HelpTestCase(SambaToolCmdTest): """Tests for samba-tool help and --help @@ -47,7 +47,8 @@ def test_help_tree(self): except BlackboxProcessError as e: output = e.stdout failed_commands.append(c) - + if isinstance(output, binary_type): + output = output.decode('utf8') tail = output.partition('Available subcommands:')[2] subcommands = re.findall(r'^\s*([\w-]+)\s+-', tail, re.MULTILINE) @@ -61,7 +62,8 @@ def test_help_tree(self): except BlackboxProcessError as e: output2 = e.stdout failed_commands.append(c) - + if isinstance(output2, binary_type): + output2 = output2.decode('utf8') self.assertEqual(output, output2) if not new_commands: From d27d817994f859368829980416b708e528ee1fb6 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 27 Apr 2018 15:49:40 +0100 Subject: [PATCH 042/122] s4/selftest: enable samba.tests.samba_tool.help for py3 --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 3b4c6b6902e..61d10ca1edd 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -623,7 +623,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.schema") planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.ntacl", py3_compatible=True) planpythontestsuite("none", "samba.tests.samba_tool.provision_password_check", py3_compatible=True) -planpythontestsuite("none", "samba.tests.samba_tool.help") +planpythontestsuite("none", "samba.tests.samba_tool.help", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.passwordsettings") # Run these against chgdcpass to share the runtime load From fa179595865ace92999b6349dba86ba6d543ef32 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 30 Apr 2018 15:47:05 +0100 Subject: [PATCH 043/122] s4/selftest: Enable samba.tests.samba_tool.sites for py3 --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 61d10ca1edd..5bed5014fbf 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -627,7 +627,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.passwordsettings") # Run these against chgdcpass to share the runtime load -planpythontestsuite("chgdcpass:local", "samba.tests.samba_tool.sites") +planpythontestsuite("chgdcpass:local", "samba.tests.samba_tool.sites", py3_compatible=True) planpythontestsuite("chgdcpass:local", "samba.tests.samba_tool.dnscmd") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.rpcecho", py3_compatible=True) From 0a385f0ab0863dfcd82d2cfa56012a9e78edc8cc Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 30 Apr 2018 16:06:12 +0100 Subject: [PATCH 044/122] s4/selftest: enable samba.tests.samba_tool.dnscmd for py3 --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 5bed5014fbf..9cf01eddd4f 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -628,7 +628,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex # Run these against chgdcpass to share the runtime load planpythontestsuite("chgdcpass:local", "samba.tests.samba_tool.sites", py3_compatible=True) -planpythontestsuite("chgdcpass:local", "samba.tests.samba_tool.dnscmd") +planpythontestsuite("chgdcpass:local", "samba.tests.samba_tool.dnscmd", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.rpcecho", py3_compatible=True) From 594a0272cc786b73ef230a3f088df18822d810b5 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 30 Apr 2018 16:20:05 +0100 Subject: [PATCH 045/122] s4/selftest: enable samba.tests.dcerpc.dnsserver for python3 --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 9cf01eddd4f..f4f36808f6d 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -641,7 +641,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex "ad_dc_ntvfs:local", "samba.tests.dcerpc.registry", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) -planoldpythontestsuite("ad_dc_ntvfs", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"']) +planoldpythontestsuite("ad_dc_ntvfs", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) planoldpythontestsuite("ad_dc", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"']) planoldpythontestsuite("chgdcpass", "samba.tests.dcerpc.raw_protocol", extra_args=['-U"$USERNAME%$PASSWORD"']) if have_heimdal_support: From c294473046d6a734188f99f397793443c42a5f42 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 30 Apr 2018 16:35:59 +0100 Subject: [PATCH 046/122] s4/selftest: enable samba.tests.dcerpc.dnsserver(ad_dc) for python3 --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index f4f36808f6d..3f2e8eb7701 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -642,7 +642,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) planoldpythontestsuite("ad_dc_ntvfs", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) -planoldpythontestsuite("ad_dc", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"']) +planoldpythontestsuite("ad_dc", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) planoldpythontestsuite("chgdcpass", "samba.tests.dcerpc.raw_protocol", extra_args=['-U"$USERNAME%$PASSWORD"']) if have_heimdal_support: planoldpythontestsuite("ad_dc:local", "samba.tests.auth_log", extra_args=['-U"$USERNAME%$PASSWORD"'], From 7b8edac7194a8d7f5740cc56252394e885848906 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 30 Apr 2018 18:31:36 +0100 Subject: [PATCH 047/122] python/samba/tests: ensure byte content (not strings) --- python/samba/tests/dcerpc/raw_testcase.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/samba/tests/dcerpc/raw_testcase.py b/python/samba/tests/dcerpc/raw_testcase.py index 15bf92993b1..fc89f70f1d3 100644 --- a/python/samba/tests/dcerpc/raw_testcase.py +++ b/python/samba/tests/dcerpc/raw_testcase.py @@ -138,7 +138,7 @@ def do_generic_bind(self, ctx, auth_context=None, ctx_list = [ctx] if auth_context is not None: - from_server = "" + from_server = b"" (finished, to_server) = auth_context["gensec"].update(from_server) self.assertFalse(finished) @@ -147,7 +147,7 @@ def do_generic_bind(self, ctx, auth_context=None, auth_context_id=auth_context["auth_context_id"], auth_blob=to_server) else: - auth_info = "" + auth_info = b"" req = self.generate_bind(call_id=call_id, pfc_flags=pfc_flags, @@ -331,14 +331,14 @@ def do_single_request(self, call_id, ctx, io, else: sig_size = 16 - zero_sig = "\x00"*sig_size + zero_sig = b"\x00"*sig_size auth_info = self.generate_auth(auth_type=auth_context["auth_type"], auth_level=auth_context["auth_level"], auth_pad_length=auth_pad_length, auth_context_id=auth_context["auth_context_id"], auth_blob=zero_sig) else: - auth_info="" + auth_info=b"" pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST pfc_flags |= samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST @@ -613,7 +613,7 @@ def generate_auth(self, if hexdump: sys.stderr.write("generate_auth: %d\n%s" % (len(ai), self.hexdump(ai))) else: - ai = "" + ai = b"" return ai From 4980c98b7f1f20d37d131edf23571edcdd807d2c Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 30 Apr 2018 18:43:54 +0100 Subject: [PATCH 048/122] python/samba/tests: Py2/Py3 allow import of ndr_(un)pack to work --- python/samba/tests/dcerpc/raw_testcase.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/python/samba/tests/dcerpc/raw_testcase.py b/python/samba/tests/dcerpc/raw_testcase.py index fc89f70f1d3..05ab560276f 100644 --- a/python/samba/tests/dcerpc/raw_testcase.py +++ b/python/samba/tests/dcerpc/raw_testcase.py @@ -26,7 +26,7 @@ from samba import gensec from samba.credentials import Credentials from samba.tests import TestCase - +from samba.ndr import ndr_pack, ndr_unpack class RawDCERPCTest(TestCase): """A raw DCE/RPC Test case.""" @@ -424,7 +424,7 @@ def do_single_request(self, call_id, ctx, io, if hexdump: sys.stderr.write("stub_out: %d\n%s" % (len(stub_out), self.hexdump(stub_out))) - samba.ndr.ndr_unpack_out(io, stub_out, bigendian=bigendian, ndr64=ndr64, + ndr_unpack_out(io, stub_out, bigendian=bigendian, ndr64=ndr64, allow_remaining=allow_remaining) if ndr_print: sys.stderr.write("out: %s" % samba.ndr.ndr_print_out(io)) @@ -441,7 +441,7 @@ def epmap_reconnect(self, abstract, transfer=None, object=None): ctx = self.prepare_presentation(samba.dcerpc.epmapper.abstract_syntax(), transfer, context_id=0) - data1 = samba.ndr.ndr_pack(abstract) + data1 = ndr_pack(abstract) lhs1 = samba.dcerpc.epmapper.epm_lhs() lhs1.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_UUID lhs1.lhs_data = data1[:18] @@ -450,7 +450,7 @@ def epmap_reconnect(self, abstract, transfer=None, object=None): floor1 = samba.dcerpc.epmapper.epm_floor() floor1.lhs = lhs1 floor1.rhs = rhs1 - data2 = samba.ndr.ndr_pack(transfer) + data2 = ndr_pack(transfer) lhs2 = samba.dcerpc.epmapper.epm_lhs() lhs2.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_UUID lhs2.lhs_data = data2[:18] @@ -515,7 +515,7 @@ def send_pdu(self, req, ndr_print=None, hexdump=None): if hexdump is None: hexdump = self.do_hexdump try: - req_pdu = samba.ndr.ndr_pack(req) + req_pdu = ndr_pack(req) if ndr_print: sys.stderr.write("send_pdu: %s" % samba.ndr.ndr_print(req)) if hexdump: @@ -573,7 +573,7 @@ def recv_pdu_raw(self, ndr_print=None, hexdump=None, timeout=None): rep_pdu = self.recv_raw(hexdump=hexdump, timeout=timeout) if rep_pdu is None: return (None,None) - rep = samba.ndr.ndr_unpack(samba.dcerpc.dcerpc.ncacn_packet, rep_pdu, allow_remaining=True) + rep = ndr_unpack(samba.dcerpc.dcerpc.ncacn_packet, rep_pdu, allow_remaining=True) if ndr_print: sys.stderr.write("recv_pdu: %s" % samba.ndr.ndr_print(rep)) self.assertEqual(rep.frag_length, len(rep_pdu)) @@ -607,7 +607,7 @@ def generate_auth(self, a.auth_context_id= auth_context_id a.credentials = auth_blob - ai = samba.ndr.ndr_pack(a) + ai = ndr_pack(a) if ndr_print: sys.stderr.write("generate_auth: %s" % samba.ndr.ndr_print(a)) if hexdump: @@ -628,7 +628,7 @@ def parse_auth(self, auth_info, ndr_print=None, hexdump=None): if hexdump: sys.stderr.write("parse_auth: %d\n%s" % (len(auth_info), self.hexdump(auth_info))) - a = samba.ndr.ndr_unpack(samba.dcerpc.dcerpc.auth, auth_info, allow_remaining=True) + a = ndr_unpack(samba.dcerpc.dcerpc.auth, auth_info, allow_remaining=True) if ndr_print: sys.stderr.write("parse_auth: %s" % samba.ndr.ndr_print(a)) @@ -661,7 +661,7 @@ def generate_pdu(self, ptype, call_id, payload, p.call_id = call_id p.u = payload - pdu = samba.ndr.ndr_pack(p) + pdu = ndr_pack(p) p.frag_length = len(pdu) return p From d259621fa6c8017c8db7443c8d210df15a17208e Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 1 May 2018 12:24:47 +0100 Subject: [PATCH 049/122] python/samba/test/dcerpc: Py3 port of samba.tests.dcerpc.raw_protocol Port code to allow this test run with either py2 or py3 Signed-off-by: Noel Power --- python/samba/tests/dcerpc/raw_protocol.py | 339 +++++++++++++++--------------- python/samba/tests/dcerpc/raw_testcase.py | 31 +-- 2 files changed, 189 insertions(+), 181 deletions(-) diff --git a/python/samba/tests/dcerpc/raw_protocol.py b/python/samba/tests/dcerpc/raw_protocol.py index ff815e97ca6..ccd4102a95d 100755 --- a/python/samba/tests/dcerpc/raw_protocol.py +++ b/python/samba/tests/dcerpc/raw_protocol.py @@ -31,6 +31,7 @@ import struct from samba import gensec from samba.tests.dcerpc.raw_testcase import RawDCERPCTest +from samba.compat import binary_type global_ndr_print = False global_hexdump = False @@ -71,13 +72,13 @@ def _test_no_auth_request_bind_pfc_flags(self, req_pfc_flags, rep_pfc_flags): self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) # And now try a request req = self.generate_request(call_id = 1, context_id=ctx1.context_id, opnum=0, - stub="") + stub=b"") self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, @@ -116,7 +117,7 @@ def _test_no_auth_request_alter_pfc_flags(self, req_pfc_flags, rep_pfc_flags): self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) # And now try a alter context req = self.generate_alter(call_id=0, pfc_flags=req_pfc_flags, ctx_list=[ctx1]) @@ -138,13 +139,13 @@ def _test_no_auth_request_alter_pfc_flags(self, req_pfc_flags, rep_pfc_flags): self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) # And now try a request req = self.generate_request(call_id = 1, context_id=ctx1.context_id, opnum=0, - stub="") + stub=b"") self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, @@ -370,7 +371,7 @@ def test_no_auth_no_ctx(self): self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) self.assertEquals(len(rep.u._pad), 3) - self.assertEquals(rep.u._pad, '\0' * 3) + self.assertEquals(rep.u._pad, b'\0' * 3) def test_invalid_auth_noctx(self): req = self.generate_bind(call_id=0) @@ -385,7 +386,7 @@ def test_invalid_auth_noctx(self): self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) self.assertEquals(len(rep.u._pad), 3) - self.assertEquals(rep.u._pad, '\0' * 3) + self.assertEquals(rep.u._pad, b'\0' * 3) def test_no_auth_valid_valid_request(self): ndr32 = base.transfer_syntax_ndr() @@ -408,14 +409,14 @@ def test_no_auth_valid_valid_request(self): self.assertEquals(rep.u.secondary_address_size, 4) self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) self.assertEquals(len(rep.u._pad1), 2) - self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u._pad1, b'\0' * 2) self.assertEquals(rep.u.num_results, 1) self.assertEquals(rep.u.ctx_list[0].result, dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) # Send a bind again tsf2_list = [ndr32] @@ -436,7 +437,7 @@ def test_no_auth_valid_valid_request(self): self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) self.assertEquals(len(rep.u._pad), 3) - self.assertEquals(rep.u._pad, '\0' * 3) + self.assertEquals(rep.u._pad, b'\0' * 3) # wait for a disconnect rep = self.recv_pdu() @@ -456,7 +457,7 @@ def test_no_auth_invalid_valid_request(self): self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) self.assertEquals(len(rep.u._pad), 3) - self.assertEquals(rep.u._pad, '\0' * 3) + self.assertEquals(rep.u._pad, b'\0' * 3) # wait for a disconnect rep = self.recv_pdu() @@ -484,14 +485,14 @@ def test_alter_no_auth_no_ctx(self): self.assertEquals(rep.u.secondary_address_size, 4) self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) self.assertEquals(len(rep.u._pad1), 2) - self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u._pad1, b'\0' * 2) self.assertEquals(rep.u.num_results, 1) self.assertEquals(rep.u.ctx_list[0].result, dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) # Send a alter req = self.generate_alter(call_id=1, ctx_list=[]) @@ -537,14 +538,14 @@ def test_no_auth_presentation_ctx_valid1(self): self.assertEquals(rep.u.secondary_address_size, 4) self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) self.assertEquals(len(rep.u._pad1), 2) - self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u._pad1, b'\0' * 2) self.assertEquals(rep.u.num_results, 1) self.assertEquals(rep.u.ctx_list[0].result, dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) # Send a alter req = self.generate_alter(call_id=1, ctx_list=[ctx1]) @@ -564,12 +565,12 @@ def test_no_auth_presentation_ctx_valid1(self): self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) req = self.generate_request(call_id = 2, context_id=ctx1.context_id, opnum=0xffff, - stub="") + stub=b"") self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, @@ -607,14 +608,14 @@ def test_no_auth_presentation_ctx_invalid1(self): self.assertEquals(rep.u.secondary_address_size, 4) self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) self.assertEquals(len(rep.u._pad1), 2) - self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u._pad1, b'\0' * 2) self.assertEquals(rep.u.num_results, 1) self.assertEquals(rep.u.ctx_list[0].result, dcerpc.DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION) self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) # Send a alter req = self.generate_alter(call_id=1, ctx_list=[ctx1]) @@ -634,12 +635,12 @@ def test_no_auth_presentation_ctx_invalid1(self): self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) req = self.generate_request(call_id = 2, context_id=12345, opnum=0, - stub="") + stub=b"") self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, @@ -672,7 +673,7 @@ def test_no_auth_presentation_ctx_invalid1(self): self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) def test_no_auth_presentation_ctx_invalid2(self): ndr32 = base.transfer_syntax_ndr() @@ -697,7 +698,7 @@ def test_no_auth_presentation_ctx_invalid2(self): self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) self.assertEquals(len(rep.u._pad), 3) - self.assertEquals(rep.u._pad, '\0' * 3) + self.assertEquals(rep.u._pad, b'\0' * 3) # wait for a disconnect rep = self.recv_pdu() @@ -727,14 +728,14 @@ def test_no_auth_presentation_ctx_invalid3(self): self.assertEquals(rep.u.secondary_address_size, 4) self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) self.assertEquals(len(rep.u._pad1), 2) - self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u._pad1, b'\0' * 2) self.assertEquals(rep.u.num_results, 1) self.assertEquals(rep.u.ctx_list[0].result, dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) tsf1b_list = [] ctx1b = dcerpc.ctx_list() @@ -788,14 +789,14 @@ def test_no_auth_presentation_ctx_invalid4(self): self.assertEquals(rep.u.secondary_address_size, 4) self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) self.assertEquals(len(rep.u._pad1), 2) - self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u._pad1, b'\0' * 2) self.assertEquals(rep.u.num_results, 1) self.assertEquals(rep.u.ctx_list[0].result, dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) # With a known but wrong syntax we get a protocol error # see test_no_auth_presentation_ctx_valid2 @@ -850,14 +851,14 @@ def test_no_auth_presentation_ctx_valid2(self): self.assertEquals(rep.u.secondary_address_size, 4) self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) self.assertEquals(len(rep.u._pad1), 2) - self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u._pad1, b'\0' * 2) self.assertEquals(rep.u.num_results, 1) self.assertEquals(rep.u.ctx_list[0].result, dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) # With a unknown but wrong syntaxes we get NO protocol error # see test_no_auth_presentation_ctx_invalid4 @@ -886,12 +887,12 @@ def test_no_auth_presentation_ctx_valid2(self): self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) req = self.generate_request(call_id = 2, context_id=ctx1a.context_id, opnum=0xffff, - stub="") + stub=b"") self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, @@ -928,14 +929,14 @@ def test_no_auth_presentation_ctx_no_ndr64(self): self.assertEquals(rep.u.secondary_address_size, 4) self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) self.assertEquals(len(rep.u._pad1), 2) - self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u._pad1, b'\0' * 2) self.assertEquals(rep.u.num_results, 1) self.assertEquals(rep.u.ctx_list[0].result, dcerpc.DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION) self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) tsf0_list = [ndr32] ctx0 = dcerpc.ctx_list() @@ -961,12 +962,12 @@ def test_no_auth_presentation_ctx_no_ndr64(self): self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) req = self.generate_request(call_id = 1, context_id=ctx0.context_id, opnum=0, - stub="") + stub=b"") self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, @@ -1000,12 +1001,12 @@ def test_no_auth_presentation_ctx_no_ndr64(self): self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) req = self.generate_request(call_id = 1, context_id=ctx1.context_id, opnum=0, - stub="") + stub=b"") self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, @@ -1039,12 +1040,12 @@ def test_no_auth_presentation_ctx_no_ndr64(self): self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) req = self.generate_request(call_id = 1, context_id=ctx2.context_id, opnum=0, - stub="") + stub=b"") self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, @@ -1090,12 +1091,12 @@ def test_no_auth_presentation_ctx_no_ndr64(self): self.assertEquals(rep.u.ctx_list[1].reason, dcerpc.DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED) self.assertNDRSyntaxEquals(rep.u.ctx_list[1].syntax, zero_syntax) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) req = self.generate_request(call_id = 1, context_id=ctx3.context_id, opnum=0, - stub="") + stub=b"") self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, @@ -1127,12 +1128,12 @@ def test_no_auth_presentation_ctx_no_ndr64(self): self.assertEquals(rep.u.ctx_list[1].reason, dcerpc.DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED) self.assertNDRSyntaxEquals(rep.u.ctx_list[1].syntax, zero_syntax) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) req = self.generate_request(call_id = 1, context_id=ctx4.context_id, opnum=0, - stub="") + stub=b"") self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, @@ -1145,7 +1146,7 @@ def test_no_auth_presentation_ctx_no_ndr64(self): req = self.generate_request(call_id = 1, context_id=ctx3.context_id, opnum=0, - stub="") + stub=b"") self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, @@ -1177,12 +1178,12 @@ def test_no_auth_presentation_ctx_no_ndr64(self): self.assertEquals(rep.u.ctx_list[1].reason, dcerpc.DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED) self.assertNDRSyntaxEquals(rep.u.ctx_list[1].syntax, zero_syntax) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) req = self.generate_request(call_id = 1, context_id=ctx4.context_id, opnum=0, - stub="") + stub=b"") self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, @@ -1195,7 +1196,7 @@ def test_no_auth_presentation_ctx_no_ndr64(self): req = self.generate_request(call_id = 1, context_id=ctx3.context_id, opnum=0, - stub="") + stub=b"") self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, @@ -1241,12 +1242,12 @@ def test_no_auth_presentation_ctx_no_ndr64(self): self.assertEquals(rep.u.ctx_list[1].reason, dcerpc.DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED) self.assertNDRSyntaxEquals(rep.u.ctx_list[1].syntax, zero_syntax) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) req = self.generate_request(call_id = 1, context_id=ctx5mgmt.context_id, opnum=0, - stub="") + stub=b"") self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, @@ -1278,12 +1279,12 @@ def test_no_auth_presentation_ctx_no_ndr64(self): self.assertEquals(rep.u.ctx_list[1].reason, dcerpc.DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED) self.assertNDRSyntaxEquals(rep.u.ctx_list[1].syntax, zero_syntax) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) req = self.generate_request(call_id = 1, context_id=ctx5mgmt.context_id, opnum=0, - stub="") + stub=b"") self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, @@ -1317,13 +1318,13 @@ def test_no_auth_bind_time_none_simple(self): self.assertEquals(rep.u.secondary_address_size, 4) self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) self.assertEquals(len(rep.u._pad1), 2) - self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u._pad1, b'\0' * 2) self.assertEquals(rep.u.num_results, 1) self.assertEquals(rep.u.ctx_list[0].result, dcerpc.DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK) self.assertEquals(rep.u.ctx_list[0].reason, features) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) def test_no_auth_bind_time_none_ignore_additional(self): features1 = 0 @@ -1354,13 +1355,13 @@ def test_no_auth_bind_time_none_ignore_additional(self): self.assertEquals(rep.u.secondary_address_size, 4) self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) self.assertEquals(len(rep.u._pad1), 2) - self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u._pad1, b'\0' * 2) self.assertEquals(rep.u.num_results, 1) self.assertEquals(rep.u.ctx_list[0].result, dcerpc.DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK) self.assertEquals(rep.u.ctx_list[0].reason, features1) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) def test_no_auth_bind_time_only_first(self): features1 = dcerpc.DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN @@ -1389,14 +1390,14 @@ def test_no_auth_bind_time_only_first(self): self.assertEquals(rep.u.secondary_address_size, 4) self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) self.assertEquals(len(rep.u._pad1), 2) - self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u._pad1, b'\0' * 2) self.assertEquals(rep.u.num_results, 1) self.assertEquals(rep.u.ctx_list[0].result, dcerpc.DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION) self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) def test_no_auth_bind_time_twice(self): features1 = dcerpc.DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN @@ -1432,7 +1433,7 @@ def test_no_auth_bind_time_twice(self): self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) self.assertEquals(len(rep.u._pad), 3) - self.assertEquals(rep.u._pad, '\0' * 3) + self.assertEquals(rep.u._pad, b'\0' * 3) # wait for a disconnect rep = self.recv_pdu() @@ -1463,13 +1464,13 @@ def test_no_auth_bind_time_keep_on_orphan_simple(self): self.assertEquals(rep.u.secondary_address_size, 4) self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) self.assertEquals(len(rep.u._pad1), 2) - self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u._pad1, b'\0' * 2) self.assertEquals(rep.u.num_results, 1) self.assertEquals(rep.u.ctx_list[0].result, dcerpc.DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK) self.assertEquals(rep.u.ctx_list[0].reason, features) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) def test_no_auth_bind_time_keep_on_orphan_ignore_additional(self): features1 = dcerpc.DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN @@ -1499,13 +1500,13 @@ def test_no_auth_bind_time_keep_on_orphan_ignore_additional(self): self.assertEquals(rep.u.secondary_address_size, 4) self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) self.assertEquals(len(rep.u._pad1), 2) - self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u._pad1, b'\0' * 2) self.assertEquals(rep.u.num_results, 1) self.assertEquals(rep.u.ctx_list[0].result, dcerpc.DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK) self.assertEquals(rep.u.ctx_list[0].reason, features1) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) def _test_auth_type_level_bind_nak(self, auth_type, auth_level, creds=None, reason=dcerpc.DCERPC_BIND_NAK_REASON_INVALID_AUTH_TYPE): @@ -1528,7 +1529,7 @@ def _test_auth_type_level_bind_nak(self, auth_type, auth_level, creds=None, auth_level=auth_level, auth_context_id=auth_context_id, g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY) - from_server = "" + from_server = b"" (finished, to_server) = auth_context["gensec"].update(from_server) self.assertFalse(finished) @@ -1537,7 +1538,7 @@ def _test_auth_type_level_bind_nak(self, auth_type, auth_level, creds=None, auth_context_id=auth_context["auth_context_id"], auth_blob=to_server) else: - to_server = "none" + to_server = b"none" auth_info = self.generate_auth(auth_type=auth_type, auth_level=auth_level, auth_context_id=auth_context_id, @@ -1555,7 +1556,7 @@ def _test_auth_type_level_bind_nak(self, auth_type, auth_level, creds=None, self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) self.assertEquals(len(rep.u._pad), 3) - self.assertEquals(rep.u._pad, '\0' * 3) + self.assertEquals(rep.u._pad, b'\0' * 3) # wait for a disconnect rep = self.recv_pdu() @@ -1624,7 +1625,7 @@ def _test_auth_none_level_request(self, auth_level): self.assertEquals(rep.u.secondary_address_size, 4) self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) self.assertEquals(len(rep.u._pad1), 2) - self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u._pad1, b'\0' * 2) self.assertEquals(rep.u.num_results, 1) self.assertEquals(rep.u.ctx_list[0].result, dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) @@ -1637,7 +1638,7 @@ def _test_auth_none_level_request(self, auth_level): req = self.generate_request(call_id = 2, context_id=ctx1.context_id, opnum=0, - stub="") + stub=b"") self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, @@ -1650,12 +1651,12 @@ def _test_auth_none_level_request(self, auth_level): auth_info = self.generate_auth(auth_type=auth_type, auth_level=auth_level, auth_context_id=auth_context_id, - auth_blob="none") + auth_blob=b"none") req = self.generate_request(call_id = 3, context_id=ctx1.context_id, opnum=0, - stub="", + stub=b"", auth_info=auth_info) self.send_pdu(req) rep = self.recv_pdu() @@ -1713,14 +1714,14 @@ def _test_neg_xmit_check_values(self, self.assertEquals(rep.u.secondary_address_size, 4) self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) self.assertEquals(len(rep.u._pad1), 2) - self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u._pad1, b'\0' * 2) self.assertEquals(rep.u.num_results, 1) self.assertEquals(rep.u.ctx_list[0].result, dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) assoc_group_id = rep.u.assoc_group_id if alter_xmit is None: @@ -1751,14 +1752,14 @@ def _test_neg_xmit_check_values(self, self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) chunk_size = rep_both - dcerpc.DCERPC_REQUEST_LENGTH req = self.generate_request(call_id = 2, context_id=ctx1.context_id, opnum=0, alloc_hint=0xffffffff, - stub="\00" * chunk_size) + stub=b"\00" * chunk_size) self.send_pdu(req,ndr_print=True,hexdump=True) rep = self.recv_pdu(ndr_print=True,hexdump=True) self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, @@ -1773,7 +1774,7 @@ def _test_neg_xmit_check_values(self, context_id=ctx1.context_id, opnum=0, alloc_hint=0xffffffff, - stub="\00" * chunk_size) + stub=b"\00" * chunk_size) self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, @@ -1788,7 +1789,7 @@ def _test_neg_xmit_check_values(self, context_id=ctx1.context_id, opnum=0, alloc_hint=0xffffffff, - stub="\00" * chunk_size) + stub=b"\00" * chunk_size) self.send_pdu(req) rep = self.recv_pdu() # We get a fault @@ -1871,21 +1872,21 @@ def test_alloc_hint(self): self.assertEquals(rep.u.secondary_address_size, 4) self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) self.assertEquals(len(rep.u._pad1), 2) - self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u._pad1, b'\0' * 2) self.assertEquals(rep.u.num_results, 1) self.assertEquals(rep.u.ctx_list[0].result, dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) self.assertEquals(rep.u.ctx_list[0].reason, dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) - self.assertEquals(rep.u.auth_info, '\0' * 0) + self.assertEquals(rep.u.auth_info, b'\0' * 0) # And now try a request without auth_info req = self.generate_request(call_id = 2, context_id=ctx.context_id, opnum=0, alloc_hint=0xffffffff, - stub="") + stub=b"") self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, @@ -1899,7 +1900,7 @@ def test_alloc_hint(self): context_id=ctx.context_id, opnum=1, alloc_hint=0xffffffff, - stub="\04\00\00\00\00\00\00\00") + stub=b"\04\00\00\00\00\00\00\00") self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, @@ -1913,7 +1914,7 @@ def test_alloc_hint(self): context_id=ctx.context_id, opnum=1, alloc_hint=1, - stub="\04\00\00\00\00\00\00\00") + stub=b"\04\00\00\00\00\00\00\00") self.send_pdu(req) rep = self.recv_pdu() self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, @@ -1931,20 +1932,26 @@ def _get_netlogon_ctx(self): epmap=True, return_ack=True) server = '\\\\' + self.target_hostname - server_utf16 = unicode(server, 'utf-8').encode('utf-16-le') + if isinstance(server, binary_type): + server_utf16 = server.decode('utf-8').encode('utf-16-le') + else: + server_utf16 = server.encode('utf-16-le') computer = 'UNKNOWNCOMPUTER' - computer_utf16 = unicode(computer, 'utf-8').encode('utf-16-le') + if isinstance(server, binary_type): + computer_utf16 = computer.decode('utf-8').encode('utf-16-le') + else: + computer_utf16 = computer.encode('utf-16-le') real_stub = struct.pack(' 0: auth_pad_length = dcerpc.DCERPC_AUTH_PAD_ALIGNMENT - mod_len - stub_bin += '\x00' * auth_pad_length + stub_bin += b'\x00' * auth_pad_length if g_auth_level >= dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY: sig_size = g.sig_size(len(stub_bin)) else: sig_size = 16 - zero_sig = "\x00"*sig_size + zero_sig = b"\x00"*sig_size auth_info = self.generate_auth(auth_type=auth_type, auth_level=auth_level, @@ -4645,15 +4652,15 @@ def _test_spnego_signing_auth_level_request(self, auth_level): auth_context_id=auth_context_id, ctx=ctx1) - stub_bin = '\x00' * 0 + stub_bin = b'\x00' * 0 mod_len = len(stub_bin) % dcerpc.DCERPC_AUTH_PAD_ALIGNMENT auth_pad_length = 0 if mod_len > 0: auth_pad_length = dcerpc.DCERPC_AUTH_PAD_ALIGNMENT - mod_len - stub_bin += '\x00' * auth_pad_length + stub_bin += b'\x00' * auth_pad_length sig_size = g.sig_size(len(stub_bin)) - zero_sig = "\x00"*sig_size + zero_sig = b"\x00"*sig_size auth_info = self.generate_auth(auth_type=auth_type, auth_level=auth_level, @@ -4711,15 +4718,15 @@ def _test_spnego_signing_auth_level_request(self, auth_level): g.check_packet(rep_data, rep_whole, rep_sig) - stub_bin = '\x00' * 17 + stub_bin = b'\x00' * 17 mod_len = len(stub_bin) % dcerpc.DCERPC_AUTH_PAD_ALIGNMENT auth_pad_length = 0 if mod_len > 0: auth_pad_length = dcerpc.DCERPC_AUTH_PAD_ALIGNMENT - mod_len - stub_bin += '\x00' * auth_pad_length + stub_bin += b'\x00' * auth_pad_length sig_size = g.sig_size(len(stub_bin)) - zero_sig = "\x00"*sig_size + zero_sig = b"\x00"*sig_size auth_info = self.generate_auth(auth_type=auth_type, auth_level=auth_level, @@ -4762,15 +4769,15 @@ def _test_spnego_signing_auth_level_request(self, auth_level): self.assertEquals(rep.u.reserved, 0) self.assertEquals(len(rep.u.error_and_verifier), 0) - stub_bin = '\x00' * 8 + stub_bin = b'\x00' * 8 mod_len = len(stub_bin) % dcerpc.DCERPC_AUTH_PAD_ALIGNMENT auth_pad_length = 0 if mod_len > 0: auth_pad_length = dcerpc.DCERPC_AUTH_PAD_ALIGNMENT - mod_len - stub_bin += '\x00' * auth_pad_length + stub_bin += b'\x00' * auth_pad_length sig_size = g.sig_size(len(stub_bin)) - zero_sig = "\x00"*sig_size + zero_sig = b"\x00"*sig_size auth_info = self.generate_auth(auth_type=auth_type, auth_level=auth_level, @@ -4827,15 +4834,15 @@ def _test_spnego_signing_auth_level_request(self, auth_level): g.check_packet(rep_data, rep_whole, rep_sig) - stub_bin = '\x00' * 8 + stub_bin = b'\x00' * 8 mod_len = len(stub_bin) % dcerpc.DCERPC_AUTH_PAD_ALIGNMENT auth_pad_length = 0 if mod_len > 0: auth_pad_length = dcerpc.DCERPC_AUTH_PAD_ALIGNMENT - mod_len - stub_bin += '\x00' * auth_pad_length + stub_bin += b'\x00' * auth_pad_length sig_size = g.sig_size(len(stub_bin)) - zero_sig = "\x00"*sig_size + zero_sig = b"\x00"*sig_size auth_info = self.generate_auth(auth_type=auth_type, auth_level=auth_level, diff --git a/python/samba/tests/dcerpc/raw_testcase.py b/python/samba/tests/dcerpc/raw_testcase.py index 05ab560276f..79736bf89e9 100644 --- a/python/samba/tests/dcerpc/raw_testcase.py +++ b/python/samba/tests/dcerpc/raw_testcase.py @@ -26,7 +26,8 @@ from samba import gensec from samba.credentials import Credentials from samba.tests import TestCase -from samba.ndr import ndr_pack, ndr_unpack +from samba.ndr import ndr_pack, ndr_unpack, ndr_unpack_out +from samba.compat import text_type class RawDCERPCTest(TestCase): """A raw DCE/RPC Test case.""" @@ -164,7 +165,7 @@ def do_generic_bind(self, ctx, auth_context=None, self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) self.assertEquals(len(rep.u._pad), 3) - self.assertEquals(rep.u._pad, '\0' * 3) + self.assertEquals(rep.u._pad, b'\0' * 3) return self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, pfc_flags=pfc_flags) @@ -316,7 +317,7 @@ def do_single_request(self, call_id, ctx, io, sys.stderr.write("stub_in: %d\n%s" % (len(stub_in), self.hexdump(stub_in))) else: # only used for sig_size calculation - stub_in = '\xff' * samba.dcerpc.dcerpc.DCERPC_AUTH_PAD_ALIGNMENT + stub_in = b'\xff' * samba.dcerpc.dcerpc.DCERPC_AUTH_PAD_ALIGNMENT sig_size = 0 if auth_context is not None: @@ -324,7 +325,7 @@ def do_single_request(self, call_id, ctx, io, auth_pad_length = 0 if mod_len > 0: auth_pad_length = samba.dcerpc.dcerpc.DCERPC_AUTH_PAD_ALIGNMENT - mod_len - stub_in += '\x00' * auth_pad_length + stub_in += b'\x00' * auth_pad_length if auth_context["g_auth_level"] >= samba.dcerpc.dcerpc.DCERPC_AUTH_LEVEL_PACKET: sig_size = auth_context["gensec"].sig_size(len(stub_in)) @@ -461,19 +462,19 @@ def epmap_reconnect(self, abstract, transfer=None, object=None): floor2.rhs = rhs2 lhs3 = samba.dcerpc.epmapper.epm_lhs() lhs3.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_NCACN - lhs3.lhs_data = "" + lhs3.lhs_data = b"" floor3 = samba.dcerpc.epmapper.epm_floor() floor3.lhs = lhs3 floor3.rhs.minor_version = 0 lhs4 = samba.dcerpc.epmapper.epm_lhs() lhs4.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_TCP - lhs4.lhs_data = "" + lhs4.lhs_data = b"" floor4 = samba.dcerpc.epmapper.epm_floor() floor4.lhs = lhs4 floor4.rhs.port = self.tcp_port lhs5 = samba.dcerpc.epmapper.epm_lhs() lhs5.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_IP - lhs5.lhs_data = "" + lhs5.lhs_data = b"" floor5 = samba.dcerpc.epmapper.epm_floor() floor5.lhs = lhs5 floor5.rhs.ipaddr = "0.0.0.0" @@ -645,7 +646,7 @@ def generate_pdu(self, ptype, call_id, payload, if getattr(payload, 'auth_info', None): ai = payload.auth_info else: - ai = "" + ai = b"" p = samba.dcerpc.dcerpc.ncacn_packet() p.rpc_vers = rpc_vers @@ -679,7 +680,7 @@ def verify_pdu(self, p, ptype, call_id, if getattr(p.u, 'auth_info', None): ai = p.u.auth_info else: - ai = "" + ai = b"" self.assertEqual(p.rpc_vers, rpc_vers) self.assertEqual(p.rpc_vers_minor, rpc_vers_minor) @@ -706,7 +707,7 @@ def generate_bind(self, call_id, max_recv_frag=5840, assoc_group_id=0, ctx_list=[], - auth_info="", + auth_info=b"", ndr_print=None, hexdump=None): b = samba.dcerpc.dcerpc.bind() @@ -732,7 +733,7 @@ def generate_alter(self, call_id, max_recv_frag=5840, assoc_group_id=0, ctx_list=[], - auth_info="", + auth_info=b"", ndr_print=None, hexdump=None): a = samba.dcerpc.dcerpc.bind() @@ -754,7 +755,7 @@ def generate_alter(self, call_id, def generate_auth3(self, call_id, pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, - auth_info="", + auth_info=b"", ndr_print=None, hexdump=None): a = samba.dcerpc.dcerpc.auth3() @@ -776,7 +777,7 @@ def generate_request(self, call_id, opnum=None, object=None, stub=None, - auth_info="", + auth_info=b"", ndr_print=None, hexdump=None): if alloc_hint is None: @@ -804,7 +805,7 @@ def generate_request(self, call_id, def generate_co_cancel(self, call_id, pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, - auth_info="", + auth_info=b"", ndr_print=None, hexdump=None): c = samba.dcerpc.dcerpc.co_cancel() @@ -821,7 +822,7 @@ def generate_co_cancel(self, call_id, def generate_orphaned(self, call_id, pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, - auth_info="", + auth_info=b"", ndr_print=None, hexdump=None): o = samba.dcerpc.dcerpc.orphaned() From f7c6e92a17cb7bdf9dfdeb597ea111f54f5a7c93 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 1 May 2018 19:58:36 +0100 Subject: [PATCH 050/122] python/samba/tests: Py2/Py3 port for hexdump --- python/samba/tests/__init__.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 7061f8b3d14..6c24530a1ed 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -36,6 +36,7 @@ import samba.auth import samba.dcerpc.base from samba.compat import PY3, text_type +from samba.compat import string_types from random import randint if not PY3: # Py2 only @@ -50,7 +51,7 @@ class SkipTest(Exception): """Test skipped.""" -HEXDUMP_FILTER=''.join([(len(repr(chr(x)))==3) and chr(x) or '.' for x in range(256)]) +HEXDUMP_FILTER=bytearray([x if ((len(repr(chr(x)))==3) and (x < 127)) else ord('.') for x in range(256)]) class TestCase(unittest.TestCase): """A Samba test case.""" @@ -80,16 +81,24 @@ def get_creds_ccache_name(self): def hexdump(self, src): N = 0 result = '' + is_string = isinstance(src, string_types) while src: ll = src[:8] lr = src[8:16] src = src[16:] - hl = ' '.join(["%02X" % ord(x) for x in ll]) - hr = ' '.join(["%02X" % ord(x) for x in lr]) - ll = ll.translate(HEXDUMP_FILTER) - lr = lr.translate(HEXDUMP_FILTER) + if is_string: + hl = ' '.join(["%02X" % ord(x) for x in ll]) + hr = ' '.join(["%02X" % ord(x) for x in lr]) + ll = ll.translate(HEXDUMP_FILTER) + lr = lr.translate(HEXDUMP_FILTER) + else: + hl = ' '.join(["%02X" % x for x in ll]) + hr = ' '.join(["%02X" % x for x in lr]) + ll = ll.translate(HEXDUMP_FILTER).decode('ascii') + lr = lr.translate(HEXDUMP_FILTER).decode('ascii') result += "[%04X] %-*s %-*s %s %s\n" % (N, 8*3, hl, 8*3, hr, ll, lr) N += 16 + print ('### DUMP %s' % result) return result def insta_creds(self, template=None, username=None, userpass=None, kerberos_state=None): From d104519cba339d28123c06d7d5bef8971a988351 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 1 May 2018 12:51:41 +0100 Subject: [PATCH 051/122] s4/selftest: enable samba.tests.dcerpc.raw_protocol for py3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 3f2e8eb7701..6cde957018a 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -643,7 +643,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planoldpythontestsuite("ad_dc_ntvfs", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) planoldpythontestsuite("ad_dc", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) -planoldpythontestsuite("chgdcpass", "samba.tests.dcerpc.raw_protocol", extra_args=['-U"$USERNAME%$PASSWORD"']) +planoldpythontestsuite("chgdcpass", "samba.tests.dcerpc.raw_protocol", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) if have_heimdal_support: planoldpythontestsuite("ad_dc:local", "samba.tests.auth_log", extra_args=['-U"$USERNAME%$PASSWORD"'], environ={'CLIENT_IP': '127.0.0.11', From 01b6c2093fd41975fddc4f0876ac0a1bf75aebe2 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 3 May 2018 19:21:00 +0100 Subject: [PATCH 052/122] python/samba/netcmd/ port samba_tool/user to be py2/py3 compatable --- python/samba/netcmd/user.py | 52 ++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/python/samba/netcmd/user.py b/python/samba/netcmd/user.py index 45a76b545d4..8ed32264df5 100644 --- a/python/samba/netcmd/user.py +++ b/python/samba/netcmd/user.py @@ -384,6 +384,8 @@ def run(self, username, password=None, credopts=None, sambaopts=None, self.outf.write("User '%s' created successfully\n" % username) from samba.compat import string_types +from samba.compat import text_type +from samba.compat import binary_type class cmd_user_add(cmd_user_create): __doc__ = cmd_user_create.__doc__ @@ -1051,7 +1053,8 @@ def get_package(name, min_idx=0): def get_utf8(a, b, username): try: - u = unicode(b, 'utf-16-le') + if isinstance(b, binary_type): + u = b.decode('utf-16-le') except UnicodeDecodeError as e: self.outf.write("WARNING: '%s': CLEARTEXT is invalid UTF-16-LE unable to generate %s\n" % ( username, a)) @@ -1748,7 +1751,6 @@ def run(self, cache_ldb_initialize=False, cache_ldb=None, sync_command = "%s" % os.path.abspath(script) else: sync_command = None - dirsync_filter = filter if dirsync_filter is None: dirsync_filter = "(&" + \ @@ -1765,12 +1767,12 @@ def run(self, cache_ldb_initialize=False, cache_ldb=None, ] dirsync_attrs = dirsync_secret_attrs + [ - "pwdLastSet", - "sAMAccountName", - "userPrincipalName", - "userAccountControl", - "isDeleted", - "isRecycled", + u"pwdLastSet", + u"sAMAccountName", + u"userPrincipalName", + u"userAccountControl", + u"isDeleted", + u"isRecycled", ] password_attrs = None @@ -1845,7 +1847,7 @@ def load_cache(): attrs=cache_attrs) if len(res) == 1: try: - self.samdb_url = res[0]["samdbUrl"][0] + self.samdb_url = res[0]["samdbUrl"][0].decode('utf8') except KeyError as e: self.samdb_url = None else: @@ -1866,13 +1868,21 @@ def load_cache(): self.sync_command = sync_command add_ldif = "dn: %s\n" % self.cache_dn add_ldif += "objectClass: userSyncPasswords\n" - add_ldif += "samdbUrl:: %s\n" % base64.b64encode(self.samdb_url).decode('utf8') - add_ldif += "dirsyncFilter:: %s\n" % base64.b64encode(self.dirsync_filter).decode('utf8') + to_encode = self.samdb_url; + # #TODO think about ensuring self.samdb_url are always text + # e.g. unicode in py2 + if isinstance(to_encode, text_type): + to_encode = to_encode.encode('utf8') + add_ldif += "samdbUrl:: %s\n" % base64.b64encode(to_encode).decode('utf8') + to_encode = self.dirsync_filter + if isinstance(to_encode, text_type): + to_encode = to_encode.encode('utf8') + add_ldif += "dirsyncFilter:: %s\n" % base64.b64encode(to_encode).decode('utf8') for a in self.dirsync_attrs: - add_ldif += "dirsyncAttribute:: %s\n" % base64.b64encode(a).decode('utf8') + add_ldif += "dirsyncAttribute:: %s\n" % base64.b64encode(a.encode('utf8')).decode('utf8') add_ldif += "dirsyncControl: %s\n" % self.dirsync_controls[0] for a in self.password_attrs: - add_ldif += "passwordAttribute:: %s\n" % base64.b64encode(a).decode('utf8') + add_ldif += "passwordAttribute:: %s\n" % base64.b64encode(a.encode('utf8')).decode('utf8') if self.decrypt_samba_gpg == True: add_ldif += "decryptSambaGPG: TRUE\n" else: @@ -1888,22 +1898,22 @@ def load_cache(): ldif = self.cache.write_ldif(msg, ldb.CHANGETYPE_NONE) self.outf.write("%s" % ldif) else: - self.dirsync_filter = res[0]["dirsyncFilter"][0] + self.dirsync_filter = res[0]["dirsyncFilter"][0].decode('utf8') self.dirsync_attrs = [] for a in res[0]["dirsyncAttribute"]: - self.dirsync_attrs.append(a) - self.dirsync_controls = [res[0]["dirsyncControl"][0], "extended_dn:1:0"] + self.dirsync_attrs.append(a.decode('utf8')) + self.dirsync_controls = [res[0]["dirsyncControl"][0].decode('utf8'), "extended_dn:1:0"] self.password_attrs = [] for a in res[0]["passwordAttribute"]: - self.password_attrs.append(a) - decrypt_string = res[0]["decryptSambaGPG"][0] + self.password_attrs.append(a.decode('utf8')) + decrypt_string = res[0]["decryptSambaGPG"][0].decode('utf8') assert(decrypt_string in ["TRUE", "FALSE"]) if decrypt_string == "TRUE": self.decrypt_samba_gpg = True else: self.decrypt_samba_gpg = False if "syncCommand" in res[0]: - self.sync_command = res[0]["syncCommand"][0] + self.sync_command = res[0]["syncCommand"][0].decode('utf8') else: self.sync_command = None if "currentPid" in res[0]: @@ -2058,6 +2068,8 @@ def update_pid(pid): try: os.ftruncate(self.lockfd, 0) if buf is not None: + if isinstance(buf, text_type): + buf = buf.encode('utf8') os.write(self.lockfd, buf) except IOError as e3: (err, msg) = e3.args @@ -2177,7 +2189,7 @@ def sync_loop(wait): else: log_msg("Getting changes\n") self.outf.write("dirsyncFilter: %s\n" % self.dirsync_filter) - self.outf.write("dirsyncControls: %r\n" % self.dirsync_controls) + self.outf.write("[2]dirsyncControls: %r\n" % self.dirsync_controls) self.outf.write("syncCommand: %s\n" % self.sync_command) dirsync_loop() From fffab315064f12677f3b9a828f7395f7a0134209 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 3 May 2018 19:28:31 +0100 Subject: [PATCH 053/122] python/samba/tests: make samba/tests/samba_tool/user py2/py3 compat --- python/samba/tests/samba_tool/user.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/python/samba/tests/samba_tool/user.py b/python/samba/tests/samba_tool/user.py index f99288a7cb8..483a3f17729 100644 --- a/python/samba/tests/samba_tool/user.py +++ b/python/samba/tests/samba_tool/user.py @@ -27,6 +27,8 @@ ) from samba.ndr import ndr_unpack from samba.dcerpc import drsblobs +from samba.compat import text_type +from samba.tests import env_loadparm class UserCmdTestCase(SambaToolCmdTest): """Tests for samba-tool user subcommands""" @@ -64,7 +66,13 @@ def tearDown(self): for user in self.users: if self._find_user(user["name"]): self.runsubcmd("user", "delete", user["name"]) - + lp = env_loadparm() + # python3 tests running after python2 stumble because + # the cache is still there and '--cache-ldb-initialize' + # will fail + cachedb = lp.private_path("user-syncpasswords-cache.ldb") + if os.path.exists(cachedb): + os.remove(cachedb) def test_newuser(self): # try to add all the users again, this should fail @@ -235,8 +243,12 @@ def test_setpassword(self): creds.set_password(newpasswd) nthash = creds.get_nt_hash() unicodePwd = base64.b64encode(creds.get_nt_hash()).decode('utf8') - virtualClearTextUTF8 = base64.b64encode(newpasswd).decode('utf8') - virtualClearTextUTF16 = base64.b64encode(unicode(newpasswd, 'utf-8').encode('utf-16-le')).decode('utf8') + if isinstance(newpasswd, text_type): + virtualClearTextUTF8 = base64.b64encode(newpasswd.encode('utf8')).decode('utf8') + virtualClearTextUTF16 = base64.b64encode(newpasswd.encode('utf-16-le')).decode('utf8') + else: + virtualClearTextUTF8 = base64.b64encode(text_type(newpasswd, 'utf8').encode('utf8')).decode('utf8') + virtualClearTextUTF16 = base64.b64encode(unicode(newpasswd, 'utf8').encode('utf-16-le')).decode('utf8') (result, out, err) = self.runsubcmd("user", "setpassword", user["name"], @@ -363,7 +375,7 @@ def test_list(self): for userobj in userlist: name = userobj.get("samaccountname", idx=0) - found = self.assertMatch(out, name, + found = self.assertMatch(out, name.decode('utf8'), "user '%s' not found" % name) def test_show(self): From 7a6bdfcc26ebb475c7920656a07fee13885d4d24 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 3 May 2018 19:30:06 +0100 Subject: [PATCH 054/122] s4/selftest: enable samba.tests.samba_tool.user for py3 --- source4/selftest/tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 6cde957018a..2847807eb44 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -611,9 +611,9 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.gpo", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.processes", py3_compatible=True) -planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.user") +planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.user", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.user_wdigest", py3_compatible=True) -planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.user") +planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.user", py3_compatible=True) planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.user_virtualCryptSHA") planpythontestsuite("chgdcpass:local", "samba.tests.samba_tool.user_check_password_script", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.group", py3_compatible=True) From 4f89884196333ff74beba557e47ec29e8923ff6c Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 3 May 2018 20:28:43 +0100 Subject: [PATCH 055/122] samba_tool: more changes to make samba_tool.user py2/p3 compat specifically this allows samba.tests.samba_tool.user_virtualCryptSHA to run py2/p3 compat --- python/samba/netcmd/user.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/samba/netcmd/user.py b/python/samba/netcmd/user.py index 8ed32264df5..38487f7273a 100644 --- a/python/samba/netcmd/user.py +++ b/python/samba/netcmd/user.py @@ -1188,7 +1188,7 @@ def get_virtual_crypt_value(a, algorithm, rounds, username, account_name): if b is not None: u8 = get_utf8(a, b, username or account_name) if u8 is not None: - sv = get_crypt_value(str(algorithm), u8, rounds) + sv = get_crypt_value(str(algorithm), u8.decode('utf8'), rounds) if sv is None: # Unable to calculate a hash with the specified # number of rounds, fall back to the first hash using @@ -1217,14 +1217,14 @@ def get_userPassword_hash(blob, algorithm, rounds): for h in up.hashes: if (scheme_match is None and h.scheme == SCHEME and - h.value.startswith(scheme_prefix)): + h.value.decode('utf8').startswith(scheme_prefix)): scheme_match = h.value - if h.scheme == SCHEME and h.value.startswith(prefix): - return (h.value, scheme_match) + if h.scheme == SCHEME and h.value.decode('utf8').startswith(prefix): + return (h.value.decode('utf8'), scheme_match.decode('utf8')) # No match on the number of rounds, return the value of the # first matching scheme - return (None, scheme_match) + return (None, scheme_match.decode('utf8')) # We use sort here in order to have a predictable processing order for a in sorted(virtual_attributes.keys()): From 42166155f4c67a3c558b30caeb7eeaf2a7f6adfd Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 3 May 2018 20:31:07 +0100 Subject: [PATCH 056/122] s4/selftest: enable samba.tests.samba_tool.user_virtualCryptSHA for py3 --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 2847807eb44..2d827f8b37f 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -614,7 +614,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.user", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.user_wdigest", py3_compatible=True) planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.user", py3_compatible=True) -planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.user_virtualCryptSHA") +planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.user_virtualCryptSHA", py3_compatible=True) planpythontestsuite("chgdcpass:local", "samba.tests.samba_tool.user_check_password_script", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.group", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.ou", py3_compatible=True) From 507ddaca25bbcef1df4cc24d97ac7423fbe0bee2 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 4 May 2018 09:49:29 +0100 Subject: [PATCH 057/122] s4/selftest/tests: disable some of the samba_tool.user tests for py3 Although these tests run they don't work against the current docker CI image which needs to be updated with python3-pycrypto to work. --- source4/selftest/tests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 2d827f8b37f..8169eac6d80 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -611,10 +611,10 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.gpo", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.processes", py3_compatible=True) -planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.user", py3_compatible=True) +planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.user", py3_compatible=False) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.user_wdigest", py3_compatible=True) -planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.user", py3_compatible=True) -planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.user_virtualCryptSHA", py3_compatible=True) +planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.user", py3_compatible=False) +planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.user_virtualCryptSHA", py3_compatible=False) planpythontestsuite("chgdcpass:local", "samba.tests.samba_tool.user_check_password_script", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.group", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.ou", py3_compatible=True) From ea99ed24b19aad87c04e79208a12dae2eb821392 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 9 May 2018 10:20:35 +0100 Subject: [PATCH 058/122] s4/selftest: enable tdb.python for python3 --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 8169eac6d80..ace3e7abb69 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -583,7 +583,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") +planoldpythontestsuite("none", "simple", extra_path=["%s/lib/tdb/python/tests" % srcdir()], name="tdb.python", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.sam", py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dsdb", py3_compatible=True) planpythontestsuite("none", "samba.tests.dsdb_lock", py3_compatible=True) From d385d2469ff3ff8eefd79e1c8ac782f49e724950 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 9 May 2018 11:24:48 +0100 Subject: [PATCH 059/122] python/samba/tests: make password_hash.py py2/py3 compatible --- python/samba/tests/password_hash.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/samba/tests/password_hash.py b/python/samba/tests/password_hash.py index 745ac704c9f..f4abd270204 100644 --- a/python/samba/tests/password_hash.py +++ b/python/samba/tests/password_hash.py @@ -107,7 +107,7 @@ def add_user(self, options=None, clear_text=False, ldb=None): res = self.ldb.search(base=self.ldb.get_config_basedn(), expression="ncName=%s" % self.ldb.get_default_basedn(), attrs=["nETBIOSName"]) - self.netbios_domain = res[0]["nETBIOSName"][0] + self.netbios_domain = res[0]["nETBIOSName"][0].decode('utf8') self.dns_domain = self.ldb.domain_dns_name() @@ -158,7 +158,7 @@ def get_supplemental_creds(self): # Calculate and validate a Wdigest value def check_digest(self, user, realm, password, digest): expected = calc_digest(user, realm, password) - actual = binascii.hexlify(bytearray(digest)) + actual = binascii.hexlify(bytearray(digest)).decode('utf8') error = "Digest expected[%s], actual[%s], " \ "user[%s], realm[%s], pass[%s]" % \ (expected, actual, user, realm, password) @@ -309,7 +309,7 @@ def checkUserPassword(self, up, expected): for (tag, alg, rounds) in expected: self.assertEquals(tag, up.hashes[i].scheme) - data = up.hashes[i].value.split("$") + data = up.hashes[i].value.decode('utf8').split("$") # Check we got the expected crypt algorithm self.assertEquals(alg, data[1]) @@ -320,7 +320,7 @@ def checkUserPassword(self, up, expected): # Calculate the expected hash value expected = crypt.crypt(USER_PASS, cmd) - self.assertEquals(expected, up.hashes[i].value) + self.assertEquals(expected, up.hashes[i].value.decode('utf8')) i += 1 # Check that the correct nt_hash was stored for userPassword From 765e65ef42e9d2a84359d50d964970f93de68544 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 9 May 2018 11:26:02 +0100 Subject: [PATCH 060/122] s4/selftest: enable samba.tests.password_hash_gpgme for python3 --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index ace3e7abb69..027ce6dfc7b 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -702,7 +702,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex # ad_dc:local functional_level >= 2008, gpg keys available planoldpythontestsuite("ad_dc:local", "samba.tests.password_hash_gpgme", - extra_args=['-U"$USERNAME%$PASSWORD"']) + extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) # ad_dc_ntvfs:local functional level >= 2008, gpg keys not available planoldpythontestsuite("ad_dc_ntvfs:local", "samba.tests.password_hash_fl2008", From f8f860280fcc0d6d2da55c0218394f14e1298e05 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 9 May 2018 11:27:40 +0100 Subject: [PATCH 061/122] s4/selftest: enable samba.tests.password_hash_fl2008 for python3 --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 027ce6dfc7b..2ae94288f62 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -706,7 +706,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex # ad_dc_ntvfs:local functional level >= 2008, gpg keys not available planoldpythontestsuite("ad_dc_ntvfs:local", "samba.tests.password_hash_fl2008", - extra_args=['-U"$USERNAME%$PASSWORD"']) + extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) # fl2003dc:local functional level < 2008, gpg keys not available planoldpythontestsuite("fl2003dc:local", "samba.tests.password_hash_fl2003", From 4bfd48bd3353ae521b14b9e8f435c41712e095a9 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 9 May 2018 11:37:16 +0100 Subject: [PATCH 062/122] python/samba/tests: py2/py3 compatability port Signed-off-by: Noel Power --- python/samba/tests/password_hash_ldap.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/samba/tests/password_hash_ldap.py b/python/samba/tests/password_hash_ldap.py index c2c0f781628..fac2df44f1b 100644 --- a/python/samba/tests/password_hash_ldap.py +++ b/python/samba/tests/password_hash_ldap.py @@ -48,6 +48,7 @@ from samba.credentials import Credentials import binascii import os +from samba.compat import binary_type def attid_equal(a1, a2): return (a1 & 0xffffffff) == (a2 & 0xffffffff) @@ -70,7 +71,7 @@ def get_supplemental_creds_drs(self): req8.destination_dsa_guid = null_guid req8.source_dsa_invocation_id = null_guid req8.naming_context = drsuapi.DsReplicaObjectIdentifier() - req8.naming_context.dn = unicode(dn) + req8.naming_context.dn = dn.decode('utf8') if isinstance(dn, binary_type) else dn req8.highwatermark = drsuapi.DsReplicaHighWaterMark() req8.highwatermark.tmp_highest_usn = 0 From fbdec56f858cb686d54ec9b66da16c09e35bed07 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 9 May 2018 11:37:42 +0100 Subject: [PATCH 063/122] s4/selftest: enable samba.tests.password_hash_ldap for python3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 2ae94288f62..b7dd278c894 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -710,11 +710,11 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex # fl2003dc:local functional level < 2008, gpg keys not available planoldpythontestsuite("fl2003dc:local", "samba.tests.password_hash_fl2003", - extra_args=['-U"$USERNAME%$PASSWORD"']) + extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) # ad_dc: wDigest values over ldap planoldpythontestsuite("ad_dc", "samba.tests.password_hash_ldap", - extra_args=['-U"$USERNAME%$PASSWORD"']) + extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) # Encrypted secrets # ensure default provision (ad_dc) and join (vampire_dc) # encrypt secret values on disk. From cbd80237a341bb0d644b7547245aa25a9fb1bc05 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 9 May 2018 12:07:20 +0100 Subject: [PATCH 064/122] python/samba/tests: Py2/Py3 compatability Signed-off-by: Noel Power --- python/samba/tests/encrypted_secrets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samba/tests/encrypted_secrets.py b/python/samba/tests/encrypted_secrets.py index 114f3b91108..db0822797f7 100644 --- a/python/samba/tests/encrypted_secrets.py +++ b/python/samba/tests/encrypted_secrets.py @@ -80,4 +80,4 @@ def test_required_features(self): self.assertTrue(len(res) > 0) self.assertTrue("requiredFeatures" in res[0]) required_features = res[0]["requiredFeatures"] - self.assertTrue("encryptedSecrets" in required_features) + self.assertTrue(b"encryptedSecrets" in required_features) From d88bad213676c6c00f3f9be045087696556a7393 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 9 May 2018 12:11:48 +0100 Subject: [PATCH 065/122] s4/selftest: enable samba.tests.encrypted_secrets for python3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index b7dd278c894..cbbeb224c85 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -720,16 +720,16 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex # encrypt secret values on disk. planoldpythontestsuite("ad_dc:local", "samba.tests.encrypted_secrets", - extra_args=['-U"$USERNAME%$PASSWORD"']) + extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) planoldpythontestsuite("vampire_dc:local", "samba.tests.encrypted_secrets", - extra_args=['-U"$USERNAME%$PASSWORD"']) + extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) # The fl2000dc environment is provisioned with the --plaintext_secrets option # so this test will fail, which proves the secrets are not being encrypted. # There is an entry in known_fail.d. planoldpythontestsuite("fl2000dc:local", "samba.tests.encrypted_secrets", - extra_args=['-U"$USERNAME%$PASSWORD"']) + extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.lsa_string", From 6479448ba5bde66fb711ba9508c4fe07ab3408fa Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 9 May 2018 16:09:00 +0100 Subject: [PATCH 066/122] auth/credentials: py2/py3 credential key needs to return bytes new_client_authenticator returns a dictionary. The key 'credential' needs to return bytes in Python3 Signed-off-by: Noel Power --- auth/credentials/pycredentials.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c index c626e3fa8a0..56174fefbb4 100644 --- a/auth/credentials/pycredentials.c +++ b/auth/credentials/pycredentials.c @@ -659,7 +659,7 @@ static PyObject *py_creds_new_client_authenticator(PyObject *self, netlogon_creds_client_authenticator( nc, &auth); - ret = Py_BuildValue("{ss#si}", + ret = Py_BuildValue("{s"PYARG_BYTES_LEN"si}", "credential", (const char *) &auth.cred, sizeof(auth.cred), "timestamp", auth.timestamp); From 92dc43acf38920e062bca7dd4c8230feff3a2d83 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 9 May 2018 16:11:19 +0100 Subject: [PATCH 067/122] s4/selftest: port samba.tests.py_credentials for py2/py3 compat Signed-off-by: Noel Power --- python/samba/tests/py_credentials.py | 40 ++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/python/samba/tests/py_credentials.py b/python/samba/tests/py_credentials.py index 2f5a7d61a12..757dcce7df9 100644 --- a/python/samba/tests/py_credentials.py +++ b/python/samba/tests/py_credentials.py @@ -39,8 +39,11 @@ from samba.ndr import ndr_pack from samba.samdb import SamDB from samba import NTSTATUSError, ntstatus +from samba.compat import binary_type + import ctypes + """ Integration tests for pycredentials """ @@ -48,6 +51,9 @@ MACHINE_NAME = "PCTM" USER_NAME = "PCTU" +def dump_hex(s1): + return ":".join("{:02x}".format(c if isinstance(c, int) else ord(c)) for c in s1) + class PyCredentialsTests(TestCase): def setUp(self): @@ -123,7 +129,7 @@ def test_SamLogonEx(self): validation_level, netr_flags) except NTSTATUSError as e: - enum = ctypes.c_uint32(e[0]).value + enum = ctypes.c_uint32(e.args[0]).value if enum == ntstatus.NT_STATUS_WRONG_PASSWORD: self.fail("got wrong password error") else: @@ -150,7 +156,7 @@ def test_SamLogonEx_no_domain(self): validation_level, netr_flags) except NTSTATUSError as e: - enum = ctypes.c_uint32(e[0]).value + enum = ctypes.c_uint32(e.args[0]).value if enum == ntstatus.NT_STATUS_WRONG_PASSWORD: self.fail("got wrong password error") else: @@ -176,7 +182,7 @@ def test_SamLogonExNTLM(self): validation_level, netr_flags) except NTSTATUSError as e: - enum = ctypes.c_uint32(e[0]).value + enum = ctypes.c_uint32(e.args[0]).value if enum == ntstatus.NT_STATUS_WRONG_PASSWORD: self.fail("got wrong password error") else: @@ -204,7 +210,7 @@ def test_SamLogonExMSCHAPv2(self): validation_level, netr_flags) except NTSTATUSError as e: - enum = ctypes.c_uint32(e[0]).value + enum = ctypes.c_uint32(e.args[0]).value if enum == ntstatus.NT_STATUS_WRONG_PASSWORD: self.fail("got wrong password error") else: @@ -234,10 +240,10 @@ def do_Netr_ServerPasswordSet2(self): newpass = samba.generate_random_password(PWD_LEN, PWD_LEN) encoded = newpass.encode('utf-16-le') pwd_len = len(encoded) - filler = [ord(x) for x in os.urandom(DATA_LEN-pwd_len)] + filler = [x if isinstance(x, int) else ord(x) for x in os.urandom(DATA_LEN-pwd_len)] pwd = netlogon.netr_CryptPassword() pwd.length = pwd_len - pwd.data = filler + [ord(x) for x in encoded] + pwd.data = filler + [x if isinstance(x, int) else ord(x) for x in encoded] self.machine_creds.encrypt_netr_crypt_password(pwd) c.netr_ServerPasswordSet2(self.server, self.machine_creds.get_workstation(), @@ -267,9 +273,11 @@ def create_machine_account(self): # run failed delete_force(self.ldb, self.machine_dn) - utf16pw = unicode( - '"' + self.machine_pass.encode('utf-8') + '"', 'utf-8' - ).encode('utf-16-le') + if isinstance(self.machine_pass, binary_type): + utf16pw = self.machine_pass.decode('utf8') + else: + utf16pw = self.machine_pass + utf16pw = ('"%s"' % utf16pw).encode('utf-16-le') self.ldb.add({ "dn": self.machine_dn, "objectclass": "computer", @@ -297,9 +305,11 @@ def create_user_account(self): # run failed delete_force(self.ldb, self.user_dn) - utf16pw = unicode( - '"' + self.user_pass.encode('utf-8') + '"', 'utf-8' - ).encode('utf-16-le') + if isinstance(self.user_pass, binary_type): + utf16pw = self.user_pass.decode('utf8') + else: + utf16pw = self.user_pass + utf16pw = ('"%s"' % utf16pw).encode('utf-16-le') self.ldb.add({ "dn": self.user_dn, "objectclass": "user", @@ -319,7 +329,7 @@ def create_user_account(self): def get_authenticator(self, c): auth = self.machine_creds.new_client_authenticator(); current = netr_Authenticator() - current.cred.data = [ord(x) for x in auth["credential"]] + current.cred.data = [x if isinstance(x, int) else ord(x) for x in auth["credential"]] current.timestamp = auth["timestamp"] subsequent = netr_Authenticator() @@ -367,10 +377,10 @@ def samlogon_logon_info(domain_name, computer_name, creds, logon = netlogon.netr_NetworkInfo() - logon.challenge = [ord(x) for x in challenge] + logon.challenge = [x if isinstance(x, int) else ord(x) for x in challenge] logon.nt = netlogon.netr_ChallengeResponse() logon.nt.length = len(response["nt_response"]) - logon.nt.data = [ord(x) for x in response["nt_response"]] + logon.nt.data = [x if isinstance(x, int) else ord(x) for x in response["nt_response"]] logon.identity_info = netlogon.netr_IdentityInfo() (username, domain) = creds.get_ntlm_username_domain() From 5ccf5d06624c5203c869f1950bedcd037625e9d6 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 9 May 2018 16:11:49 +0100 Subject: [PATCH 068/122] s4/selftest: enable samba.tests.py_credentials for py3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index cbbeb224c85..bd97e2609e4 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -743,7 +743,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex for env in ["ad_dc_ntvfs", "vampire_dc", "promoted_dc"]: planoldpythontestsuite(env, "samba.tests.py_credentials", - extra_args=['-U"$USERNAME%$PASSWORD"']) + extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) planoldpythontestsuite("ad_dc_ntvfs", "samba.tests.emulate.traffic", extra_args=['-U"$USERNAME%$PASSWORD"']) From c836ab097500082330a014e64b2b1bca70a3cbf9 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 9 May 2018 20:05:36 +0100 Subject: [PATCH 069/122] python/samba/tests: fix traffic for py2/py3 compatability load/save operations return randomly sorted dictionaries in python3 these changes make sure the expected results are compared with sorted actual values Signed-off-by: Noel Power --- python/samba/tests/emulate/traffic.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/python/samba/tests/emulate/traffic.py b/python/samba/tests/emulate/traffic.py index 0cfae02bce0..eb1276b55d1 100644 --- a/python/samba/tests/emulate/traffic.py +++ b/python/samba/tests/emulate/traffic.py @@ -93,8 +93,10 @@ def test_parse_ngrams_dns_included(self): f.seek(0) model2.load(f) - self.assertEqual(expected_ngrams, model2.ngrams) - self.assertEqual(expected_query_details, model2.query_details) + ngrams = {k: sorted(v) for k, v in model2.ngrams.items()} + details = {k: sorted(v) for k, v in model2.query_details.items()} + self.assertEqual(expected_ngrams, ngrams) + self.assertEqual(expected_query_details, details) def test_parse_ngrams(self): f = open(TEST_FILE) @@ -156,5 +158,7 @@ def test_parse_ngrams(self): f.seek(0) model2.load(f) - self.assertEqual(expected_ngrams, model2.ngrams) - self.assertEqual(expected_query_details, model2.query_details) + ngrams = {k: sorted(v) for k, v in model2.ngrams.items()} + details = {k: sorted(v) for k, v in model2.query_details.items()} + self.assertEqual(expected_ngrams, ngrams) + self.assertEqual(expected_query_details, details) From c9945b3b343fb24b84325811452694dadac7bd4b Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 9 May 2018 20:09:10 +0100 Subject: [PATCH 070/122] s4/selftest: enable samba.tests.emulate.traffic for py3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index bd97e2609e4..feeb330ac46 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -746,7 +746,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) planoldpythontestsuite("ad_dc_ntvfs", "samba.tests.emulate.traffic", - extra_args=['-U"$USERNAME%$PASSWORD"']) + extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) planoldpythontestsuite("ad_dc_ntvfs", "samba.tests.emulate.traffic_packet", extra_args=['-U"$USERNAME%$PASSWORD"']) From fc83de5d82e56d6fc05e11233f7d60e9e3034331 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 9 May 2018 20:17:30 +0100 Subject: [PATCH 071/122] python/samba/emulate: Fix some more missed exception tuple assignments In python3 we need to change except LdbError as e: - (status, _) = e to except LdbError as e: + (status, _) = e.args Signed-off-by: Noel Power --- python/samba/emulate/traffic.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/python/samba/emulate/traffic.py b/python/samba/emulate/traffic.py index db0fcf7788b..fd153f386ea 100644 --- a/python/samba/emulate/traffic.py +++ b/python/samba/emulate/traffic.py @@ -1568,7 +1568,7 @@ def create_ou(ldb, instance_id): ldb.add({"dn": ou.split(',', 1)[1], "objectclass": "organizationalunit"}) except LdbError as e: - (status, _) = e + (status, _) = e.args # ignore already exists if status != 68: raise @@ -1576,7 +1576,7 @@ def create_ou(ldb, instance_id): ldb.add({"dn": ou, "objectclass": "organizationalunit"}) except LdbError as e: - (status, _) = e + (status, _) = e.args # ignore already exists if status != 68: raise @@ -1626,7 +1626,7 @@ def generate_traffic_accounts(ldb, instance_id, number, password): create_machine_account(ldb, instance_id, netbios_name, password) added += 1 except LdbError as e: - (status, _) = e + (status, _) = e.args if status == 68: break else: @@ -1642,7 +1642,7 @@ def generate_traffic_accounts(ldb, instance_id, number, password): create_user_account(ldb, instance_id, username, password) added += 1 except LdbError as e: - (status, _) = e + (status, _) = e.args if status == 68: break else: @@ -1728,7 +1728,7 @@ def generate_users(ldb, instance_id, number, password): create_user_account(ldb, instance_id, username, password) users += 1 except LdbError as e: - (status, _) = e + (status, _) = e.args # Stop if entry exists if status == 68: break @@ -1752,7 +1752,7 @@ def generate_groups(ldb, instance_id, number): create_group(ldb, instance_id, name) groups += 1 except LdbError as e: - (status, _) = e + (status, _) = e.args # Stop if entry exists if status == 68: break @@ -1767,7 +1767,7 @@ def clean_up_accounts(ldb, instance_id): try: ldb.delete(ou, ["tree_delete:1"]) except LdbError as e: - (status, _) = e + (status, _) = e.args # ignore does not exist if status != 32: raise From 21afaa0854c56bbbfa8b82ede8cc5af6484da8c6 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 10 May 2018 11:57:59 +0100 Subject: [PATCH 072/122] python/samba/emulate: Various py2/py3 compatability changes Signed-off-by: Noel Power --- python/samba/emulate/traffic.py | 28 +++++++++++++++++----------- python/samba/emulate/traffic_packets.py | 10 +++++----- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/python/samba/emulate/traffic.py b/python/samba/emulate/traffic.py index fd153f386ea..a2cbd81a31a 100644 --- a/python/samba/emulate/traffic.py +++ b/python/samba/emulate/traffic.py @@ -50,6 +50,7 @@ from samba.dcerpc.misc import SEC_CHAN_BDC from samba import gensec from samba import sd_utils +from samba.compat import binary_type SLEEP_OVERHEAD = 3e-4 @@ -340,7 +341,7 @@ def __init__(self, self.last_netlogon_bad = False self.last_samlogon_bad = False self.generate_ldap_search_tables() - self.next_conversation_id = itertools.count().next + self.next_conversation_id = next(itertools.count()) def generate_ldap_search_tables(self): session = system_session() @@ -375,7 +376,7 @@ def generate_ldap_search_tables(self): # for k, v in self.dn_map.items(): # print >>sys.stderr, k, len(v) - for k, v in dn_map.items(): + for k in list(dn_map.keys()): if k[-3:] != ',DC': continue p = k[:-3] @@ -436,8 +437,8 @@ def with_random_bad_credentials(self, f, good, bad, failed_last_time): than that requested, but not significantly. """ if not failed_last_time: - if (self.badpassword_frequency > 0 and - random.random() < self.badpassword_frequency): + if (self.badpassword_frequency and self.badpassword_frequency > 0 + and random.random() < self.badpassword_frequency): try: f(bad) except: @@ -718,7 +719,7 @@ def guess_a_dns_lookup(self): def get_authenticator(self): auth = self.machine_creds.new_client_authenticator() current = netr_Authenticator() - current.cred.data = [ord(x) for x in auth["credential"]] + current.cred.data = [x if isinstance(x, int) else ord(x) for x in auth["credential"]] current.timestamp = auth["timestamp"] subsequent = netr_Authenticator() @@ -1658,9 +1659,12 @@ def create_machine_account(ldb, instance_id, netbios_name, machinepass): ou = ou_name(ldb, instance_id) dn = "cn=%s,%s" % (netbios_name, ou) - utf16pw = unicode( - '"' + machinepass.encode('utf-8') + '"', 'utf-8' - ).encode('utf-16-le') + if isinstance(machinepass, binary_type): + utf16pw = machinepass.decode('utf8') + else: + utf16pw = machinepass + utf16pw = ('"%s"' % utf16pw).encode('utf-16-le') + start = time.time() ldb.add({ "dn": dn, @@ -1678,9 +1682,11 @@ def create_user_account(ldb, instance_id, username, userpass): """Create a user account via ldap.""" ou = ou_name(ldb, instance_id) user_dn = "cn=%s,%s" % (username, ou) - utf16pw = unicode( - '"' + userpass.encode('utf-8') + '"', 'utf-8' - ).encode('utf-16-le') + if isinstance(userpass, binary_type): + utf16pw = userpass.decode('utf8') + else: + utf16pw = userpass + utf16pw = ('"%s"' % utf16pw).encode('utf-16-le') start = time.time() ldb.add({ "dn": user_dn, diff --git a/python/samba/emulate/traffic_packets.py b/python/samba/emulate/traffic_packets.py index 3f5db4317a3..3ed8887398d 100644 --- a/python/samba/emulate/traffic_packets.py +++ b/python/samba/emulate/traffic_packets.py @@ -47,7 +47,7 @@ def check_runtime_error(runtime, val): if runtime is None: return False - err32 = uint32(runtime[0]) + err32 = uint32(runtime.args[0]) if err32 == val: return True @@ -563,10 +563,10 @@ def packet_rpc_netlogon_30(packet, conversation, context): # subsequent runs newpass = context.machine_creds.get_password().encode('utf-16-le') pwd_len = len(newpass) - filler = [ord(x) for x in os.urandom(DATA_LEN - pwd_len)] + filler = [x if isinstance(x, int) else ord(x) for x in os.urandom(DATA_LEN - pwd_len)] pwd = netlogon.netr_CryptPassword() pwd.length = pwd_len - pwd.data = filler + [ord(x) for x in newpass] + pwd.data = filler + [x if isinstance(x, int) else ord(x) for x in newpass] context.machine_creds.encrypt_netr_crypt_password(pwd) c.netr_ServerPasswordSet2(context.server, # must ends with $, so use get_username instead @@ -644,10 +644,10 @@ def samlogon_logon_info(domain_name, computer_name, creds): logon = netlogon.netr_NetworkInfo() - logon.challenge = [ord(x) for x in challenge] + logon.challenge = [x if isinstance(x, int) else ord(x) for x in challenge] logon.nt = netlogon.netr_ChallengeResponse() logon.nt.length = len(response["nt_response"]) - logon.nt.data = [ord(x) for x in response["nt_response"]] + logon.nt.data = [x if isinstance(x, int) else ord(x) for x in response["nt_response"]] logon.identity_info = netlogon.netr_IdentityInfo() (username, domain) = creds.get_ntlm_username_domain() From 11bb5cbf0e821798626d6f43cce1587072293ca0 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 10 May 2018 11:58:35 +0100 Subject: [PATCH 073/122] s4/selftest: samba.tests.emulate.traffic_packet enable for py3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index feeb330ac46..e5cd6b5b12e 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -749,7 +749,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) planoldpythontestsuite("ad_dc_ntvfs", "samba.tests.emulate.traffic_packet", - extra_args=['-U"$USERNAME%$PASSWORD"']) + extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) planoldpythontestsuite("ad_dc_ntvfs", "samba.tests.blackbox.traffic_replay", extra_args=['-U"$USERNAME%$PASSWORD"']) From 8a8c37fbd1717c726e63b304074d7e9aa420c08b Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 10 May 2018 12:23:08 +0100 Subject: [PATCH 074/122] s4/selftest: samba.tests.blackbox.traffic_replay enabled for py3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index e5cd6b5b12e..a1311a68ec9 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -752,7 +752,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) planoldpythontestsuite("ad_dc_ntvfs", "samba.tests.blackbox.traffic_replay", - extra_args=['-U"$USERNAME%$PASSWORD"']) + extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) planoldpythontestsuite("ad_dc_ntvfs", "samba.tests.blackbox.traffic_learner", extra_args=['-U"$USERNAME%$PASSWORD"']) From de0188b04713c0940b7f9f705a14a624376e65cc Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 10 May 2018 12:35:58 +0100 Subject: [PATCH 075/122] python/samba/tests: Change native string to binary for py2/py3 compat Signed-off-by: Noel Power --- python/samba/tests/blackbox/traffic_learner.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/samba/tests/blackbox/traffic_learner.py b/python/samba/tests/blackbox/traffic_learner.py index edafc21384c..6e945ce680f 100644 --- a/python/samba/tests/blackbox/traffic_learner.py +++ b/python/samba/tests/blackbox/traffic_learner.py @@ -43,8 +43,8 @@ class TrafficLearnerTests(BlackboxTestCase): def test_no_output_file(self): """Run the script with no output file specified""" - expected = ("No output file was specified to write the model to.\n" - "Please specify a filename using the --out option.\n") + expected = (b"No output file was specified to write the model to.\n" + b"Please specify a filename using the --out option.\n") actual = self.check_output(LEARNER) self.assertEquals(expected, actual) From 114b5f76a6becda7f3107ed23ca90f1c8c20b3d6 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 10 May 2018 12:36:32 +0100 Subject: [PATCH 076/122] s4/selftest: Enable samba.tests.blackbox.traffic_learner for py3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index a1311a68ec9..c2766211fd3 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -755,7 +755,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) planoldpythontestsuite("ad_dc_ntvfs", "samba.tests.blackbox.traffic_learner", - extra_args=['-U"$USERNAME%$PASSWORD"']) + extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) planoldpythontestsuite("ad_dc_ntvfs", "samba.tests.blackbox.traffic_summary", extra_args=['-U"$USERNAME%$PASSWORD"']) From 3e928fbd6e04d0be2ad514c787aa5fdbfcb5129b Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 10 May 2018 12:39:36 +0100 Subject: [PATCH 077/122] s4/selftest: enable samba.tests.blackbox.traffic_summary for py3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index c2766211fd3..23a2c506c58 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -758,7 +758,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) planoldpythontestsuite("ad_dc_ntvfs", "samba.tests.blackbox.traffic_summary", - extra_args=['-U"$USERNAME%$PASSWORD"']) + extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) # # Want a selection of environments across the process models # From ac5997478575169f0b94028e49148be116664755 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 10 May 2018 12:51:19 +0100 Subject: [PATCH 078/122] s4/selftest: Enable samba.tests.blackbox.smbcontrol for py3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 23a2c506c58..f362346b1fa 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -765,7 +765,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex for env in ["ad_dc_ntvfs:local", "ad_dc:local", "fl2003dc:local", "fl2008r2dc:local", "promoted_dc:local"]: - planoldpythontestsuite(env, "samba.tests.blackbox.smbcontrol") + planoldpythontestsuite(env, "samba.tests.blackbox.smbcontrol", py3_compatible=True) plantestsuite_loadlist("samba4.ldap.python(ad_dc_ntvfs)", "ad_dc_ntvfs", [python, os.path.join(samba4srcdir, "dsdb/tests/python/ldap.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '$LOADLIST', '$LISTOPT']) plantestsuite_loadlist("samba4.tokengroups.krb5.python(ad_dc_ntvfs)", "ad_dc_ntvfs:local", [python, os.path.join(samba4srcdir, "dsdb/tests/python/token_group.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '-k', 'yes', '$LOADLIST', '$LISTOPT']) From 2dded939be87c95afbf62852daff15cdff5c9309 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 10 May 2018 13:14:22 +0100 Subject: [PATCH 079/122] python/samba/tests: remove Py2 specific imports. Remove some python2 specific import, probably this was due to previous unavailability for some c-modules in python3 Signed-off-by: Noel Power --- python/samba/tests/__init__.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 6c24530a1ed..8fba972fa03 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -38,12 +38,10 @@ from samba.compat import PY3, text_type from samba.compat import string_types from random import randint -if not PY3: - # Py2 only - from samba.samdb import SamDB - import samba.ndr - import samba.dcerpc.dcerpc - import samba.dcerpc.epmapper +from samba.samdb import SamDB +import samba.ndr +import samba.dcerpc.dcerpc +import samba.dcerpc.epmapper try: from unittest import SkipTest From f440380d2cb3760a32ea8190ae82920aa7494aee Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 10 May 2018 13:16:05 +0100 Subject: [PATCH 080/122] s4/dsdb/tests: py2/py3 porting for samba4.schemaInfo.python Signed-off-by: Noel Power --- source4/dsdb/tests/python/dsdb_schema_info.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/dsdb/tests/python/dsdb_schema_info.py b/source4/dsdb/tests/python/dsdb_schema_info.py index 648ee45b22f..42a2fd79ab7 100755 --- a/source4/dsdb/tests/python/dsdb_schema_info.py +++ b/source4/dsdb/tests/python/dsdb_schema_info.py @@ -57,8 +57,8 @@ def setUp(self): # fetch rootDSE res = self.sam_db.search(base="", expression="", scope=SCOPE_BASE, attrs=["*"]) self.assertEquals(len(res), 1) - self.schema_dn = res[0]["schemaNamingContext"][0] - self.base_dn = res[0]["defaultNamingContext"][0] + self.schema_dn = res[0]["schemaNamingContext"][0].decode('utf8') + self.base_dn = res[0]["defaultNamingContext"][0].decode('utf8') self.forest_level = int(res[0]["forestFunctionality"][0]) # get DC invocation_id From 6cbeaf175a1ac2b06323a79a63a67a9af3511561 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 10 May 2018 13:16:28 +0100 Subject: [PATCH 081/122] s4/selftest: enable samba4.schemaInfo.python for py3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index f362346b1fa..d60625c88d7 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -776,7 +776,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planoldpythontestsuite("ad_dc_ntvfs", "dsdb_schema_info", extra_path=[os.path.join(samba4srcdir, 'dsdb/tests/python')], name="samba4.schemaInfo.python(ad_dc_ntvfs)", - extra_args=['-U"$DOMAIN/$DC_USERNAME%$DC_PASSWORD"']) + extra_args=['-U"$DOMAIN/$DC_USERNAME%$DC_PASSWORD"'], py3_compatible=True) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dsdb_schema_attributes") From 2fca04bb5206179fe9213649edabf970230bf368 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 10 May 2018 16:02:29 +0100 Subject: [PATCH 082/122] python/samba/tests: some py2/py3 for samba.tests.dsdb_schema_attributes Signed-off-by: Noel Power --- python/samba/tests/dsdb_schema_attributes.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/python/samba/tests/dsdb_schema_attributes.py b/python/samba/tests/dsdb_schema_attributes.py index dbfafc4122d..5427b2a9848 100644 --- a/python/samba/tests/dsdb_schema_attributes.py +++ b/python/samba/tests/dsdb_schema_attributes.py @@ -44,8 +44,8 @@ def setUp(self): # fetch rootDSE res = self.samdb.search(base="", expression="", scope=SCOPE_BASE, attrs=["*"]) self.assertEquals(len(res), 1) - self.schema_dn = res[0]["schemaNamingContext"][0] - self.base_dn = res[0]["defaultNamingContext"][0] + self.schema_dn = res[0]["schemaNamingContext"][0].decode('utf8') + self.base_dn = res[0]["defaultNamingContext"][0].decode('utf8') self.forest_level = int(res[0]["forestFunctionality"][0]) def tearDown(self): @@ -103,7 +103,7 @@ def test_AddIndexedAttribute(self): self.assertIn(attr_ldap_name, attr_res[0]) self.assertEquals(len(attr_res[0][attr_ldap_name]), 1) - self.assertEquals(attr_res[0][attr_ldap_name][0], "CASE_INSENSITIVE") + self.assertEquals(attr_res[0][attr_ldap_name][0].decode('utf8'), "CASE_INSENSITIVE") # Check @INDEXLIST @@ -127,7 +127,7 @@ def test_AddUnIndexedAttribute(self): self.assertIn(attr_ldap_name, attr_res[0]) self.assertEquals(len(attr_res[0][attr_ldap_name]), 1) - self.assertEquals(attr_res[0][attr_ldap_name][0], "CASE_INSENSITIVE") + self.assertEquals(attr_res[0][attr_ldap_name][0].decode('utf8'), "CASE_INSENSITIVE") # Check @INDEXLIST @@ -161,11 +161,11 @@ def test_AddTwoIndexedAttributes(self): self.assertIn(attr_ldap_name, attr_res[0]) self.assertEquals(len(attr_res[0][attr_ldap_name]), 1) - self.assertEquals(attr_res[0][attr_ldap_name][0], "CASE_INSENSITIVE") + self.assertEquals(attr_res[0][attr_ldap_name][0].decode('utf8'), "CASE_INSENSITIVE") self.assertIn(attr_ldap_name2, attr_res[0]) self.assertEquals(len(attr_res[0][attr_ldap_name2]), 1) - self.assertEquals(attr_res[0][attr_ldap_name2][0], "CASE_INSENSITIVE") + self.assertEquals(attr_res[0][attr_ldap_name2][0].decode('utf8'), "CASE_INSENSITIVE") # Check @INDEXLIST @@ -189,7 +189,7 @@ def test_modify_at_attributes(self): self.assertEquals(len(res[0]), 1) self.assertTrue("@TEST_EXTRA" in res[0]) self.assertEquals(len(res[0]["@TEST_EXTRA"]), 1) - self.assertEquals(res[0]["@TEST_EXTRA"][0], "HIDDEN") + self.assertEquals(res[0]["@TEST_EXTRA"][0].decode('utf8'), "HIDDEN") samdb2 = samba.tests.connect_samdb(self.lp.samdb_url()) @@ -224,7 +224,7 @@ def test_modify_at_indexlist(self): self.assertEquals(len(res[0]), 1) self.assertTrue("@TEST_EXTRA" in res[0]) self.assertEquals(len(res[0]["@TEST_EXTRA"]), 1) - self.assertEquals(res[0]["@TEST_EXTRA"][0], "1") + self.assertEquals(res[0]["@TEST_EXTRA"][0].decode('utf8'), "1") samdb2 = samba.tests.connect_samdb(self.lp.samdb_url()) From cf5bc6c9ddd29c61333b26f2840a152b585b18e0 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 10 May 2018 16:03:36 +0100 Subject: [PATCH 083/122] There was a suggestion instead of returning a subclass of bytes/string for attribute values that would have a custom str method (which would return the decoded utf string (instead of bytes) in python3 Signed-off-by: Noel Power --- python/samba/tests/dsdb_schema_attributes.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/samba/tests/dsdb_schema_attributes.py b/python/samba/tests/dsdb_schema_attributes.py index 5427b2a9848..daa0386e58f 100644 --- a/python/samba/tests/dsdb_schema_attributes.py +++ b/python/samba/tests/dsdb_schema_attributes.py @@ -109,7 +109,7 @@ def test_AddIndexedAttribute(self): idx_res = self.samdb.search(base="@INDEXLIST", scope=ldb.SCOPE_BASE) - self.assertIn(attr_ldap_name, [str(x) for x in idx_res[0]["@IDXATTR"]]) + self.assertIn(attr_ldap_name, [x.decode('utf8') for x in idx_res[0]["@IDXATTR"]]) def test_AddUnIndexedAttribute(self): @@ -133,7 +133,7 @@ def test_AddUnIndexedAttribute(self): idx_res = self.samdb.search(base="@INDEXLIST", scope=ldb.SCOPE_BASE) - self.assertNotIn(attr_ldap_name, [str(x) for x in idx_res[0]["@IDXATTR"]]) + self.assertNotIn(attr_ldap_name, [x.decode('utf8') for x in idx_res[0]["@IDXATTR"]]) def test_AddTwoIndexedAttributes(self): @@ -171,8 +171,8 @@ def test_AddTwoIndexedAttributes(self): idx_res = self.samdb.search(base="@INDEXLIST", scope=ldb.SCOPE_BASE) - self.assertIn(attr_ldap_name, [str(x) for x in idx_res[0]["@IDXATTR"]]) - self.assertIn(attr_ldap_name2, [str(x) for x in idx_res[0]["@IDXATTR"]]) + self.assertIn(attr_ldap_name, [x.decode('utf8') for x in idx_res[0]["@IDXATTR"]]) + self.assertIn(attr_ldap_name2, [x.decode('utf8') for x in idx_res[0]["@IDXATTR"]]) def test_modify_at_attributes(self): m = {"dn": "@ATTRIBUTES", From 0ee760728b1e44ebbf109f3edcdc404737c75fac Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 10 May 2018 16:35:29 +0100 Subject: [PATCH 084/122] s4/selftest: enable samba.tests.dsdb_schema_attributes for py3 --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index d60625c88d7..709b207d860 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -778,7 +778,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex name="samba4.schemaInfo.python(ad_dc_ntvfs)", extra_args=['-U"$DOMAIN/$DC_USERNAME%$DC_PASSWORD"'], py3_compatible=True) -planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dsdb_schema_attributes") +planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dsdb_schema_attributes", py3_compatible=True) plantestsuite_loadlist("samba4.urgent_replication.python(ad_dc_ntvfs)", "ad_dc_ntvfs:local", [python, os.path.join(samba4srcdir, "dsdb/tests/python/urgent_replication.py"), '$PREFIX_ABS/ad_dc_ntvfs/private/sam.ldb', '$LOADLIST', '$LISTOPT']) plantestsuite_loadlist("samba4.ldap.dirsync.python(ad_dc_ntvfs)", "ad_dc_ntvfs", [python, os.path.join(samba4srcdir, "dsdb/tests/python/dirsync.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '$LOADLIST', '$LISTOPT']) From ff80ea9231388d38a2fde1c300f91119a4457596 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 10 May 2018 17:19:47 +0100 Subject: [PATCH 085/122] s4/selftest: enable mba4.drs.replica_sync_rodc.python for py3 Note: currently this test is skipped (although I don't see from where) more than likely the test code isn't py2/py3 compatible if it would run #FIXME --- source4/selftest/tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 709b207d860..96cf4ab2b6c 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -807,7 +807,8 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex extra_path=[os.path.join(samba4srcdir, 'torture/drs/python')], name="samba4.drs.replica_sync_rodc.python(rodc)", environ={'DC1': '$DC_SERVER', 'DC2': '$RODC_DC_SERVER'}, - extra_args=['-U$DOMAIN/$DC_USERNAME%$DC_PASSWORD']) + extra_args=['-U$DOMAIN/$DC_USERNAME%$DC_PASSWORD'], + py3_compatible=True) planoldpythontestsuite("ad_dc_ntvfs", "password_settings", extra_path=[os.path.join(samba4srcdir, 'dsdb/tests/python')], From 36403f920a60371b806a63de274c6c6988a30c11 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 10 May 2018 18:17:29 +0100 Subject: [PATCH 086/122] s3/selftst: enable samba4.tombstone_reanimation for py3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 96cf4ab2b6c..f55da63f9ef 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -834,7 +834,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planoldpythontestsuite(env, "tombstone_reanimation", name="samba4.tombstone_reanimation.python", environ={'TEST_SERVER': '$SERVER', 'TEST_USERNAME': '$USERNAME', 'TEST_PASSWORD': '$PASSWORD'}, - extra_path=[os.path.join(samba4srcdir, 'dsdb/tests/python')] + extra_path=[os.path.join(samba4srcdir, 'dsdb/tests/python')], py3_compatible=True ) planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.upgradeprovisionneeddc") From 1c64b053fbf7266e3d725c3b62beb58edf56e7a2 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 10 May 2018 18:31:46 +0100 Subject: [PATCH 087/122] python/samba/provision: py2/py3 compat for samba.tests.upgradeprovisionneeddc Signed-off-by: Noel Power --- python/samba/provision/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/samba/provision/__init__.py b/python/samba/provision/__init__.py index be792350f17..b18caa76c37 100644 --- a/python/samba/provision/__init__.py +++ b/python/samba/provision/__init__.py @@ -197,11 +197,11 @@ def find_provision_key_parameters(samdb, secretsdb, idmapdb, paths, smbconf, names.adminpass = None # NT domain, kerberos realm, root dn, domain dn, domain dns name - names.domain = string.upper(lp.get("workgroup")) + names.domain = lp.get("workgroup").upper() names.realm = lp.get("realm") names.dnsdomain = names.realm.lower() basedn = samba.dn_from_dns_name(names.dnsdomain) - names.realm = string.upper(names.realm) + names.realm = names.realm.upper() # netbiosname # Get the netbiosname first (could be obtained from smb.conf in theory) res = secretsdb.search(expression="(flatname=%s)" % From 17406a57949d807b0140cb4e6c5ecc5fff015951 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 10 May 2018 18:39:39 +0100 Subject: [PATCH 088/122] python/samba/provision: More Ldb Python3 string (str) attribute message changes --- python/samba/provision/__init__.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/samba/provision/__init__.py b/python/samba/provision/__init__.py index b18caa76c37..3ff26b69206 100644 --- a/python/samba/provision/__init__.py +++ b/python/samba/provision/__init__.py @@ -219,8 +219,8 @@ def find_provision_key_parameters(samdb, secretsdb, idmapdb, paths, smbconf, "configurationNamingContext","rootDomainNamingContext", "namingContexts"]) - names.configdn = current[0]["configurationNamingContext"][0] - names.schemadn = current[0]["schemaNamingContext"][0] + names.configdn = current[0]["configurationNamingContext"][0].decode('utf8') + names.schemadn = current[0]["schemaNamingContext"][0].decode('utf8') if not (ldb.Dn(samdb, basedn) == (ldb.Dn(samdb, current[0]["defaultNamingContext"][0].decode('utf8')))): raise ProvisioningError(("basedn in %s (%s) and from %s (%s)" @@ -237,12 +237,12 @@ def find_provision_key_parameters(samdb, secretsdb, idmapdb, paths, smbconf, for i in range(0, len(names.ncs)): nc = names.ncs[i] - dnsforestdn = "DC=ForestDnsZones,%s" % (str(names.rootdn)) + dnsforestdn = "DC=ForestDnsZones,%s" % (names.rootdn.decode('utf8')) if nc == dnsforestdn: names.dnsforestdn = dnsforestdn continue - dnsdomaindn = "DC=DomainDnsZones,%s" % (str(names.domaindn)) + dnsdomaindn = "DC=DomainDnsZones,%s" % (names.domaindn.decode('utf8')) if nc == dnsdomaindn: names.dnsdomaindn = dnsdomaindn continue @@ -442,7 +442,7 @@ def get_last_provision_usn(sam): p = re.compile(r'-') if entry[0].get("provisionnerID"): for e in entry[0]["provisionnerID"]: - myids.append(str(e)) + myids.append(e.decode('utf8')) for r in entry[0][LAST_PROVISION_USN_ATTRIBUTE]: tab1 = str(r).split(';') if len(tab1) == 2: From d792c813dd47f20d41a0322934513034c57ffd8a Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 11 May 2018 13:48:29 +0100 Subject: [PATCH 089/122] lib/ldb: Implement a bytes derived object for attributes py2/py3 ldb attributes are either bytes (py3) or str (py2) Some places in the code do str(res[0]['attribute'][0]) which results in 'result' (py2) b'result' (py3) or more commonly the attribute is used to construct a string e.g. "blah=" + res[0]['attribute'][0] + ",foo,bar=...." giving "blah=result,foo,bar=...." (py2) and very unhelpfully "blah=b'result',foo,bar=...." (py3) lots of code already constructs various strings for passing to other api using the above. To avoid many excessive res[0]['attribute'][0].decode('utf8') code like 'res[0]['attribute'][0]' will now return LdbBytes (a new object subclassing 'bytes') in py3 instead of bytes. This object has a custom '__str__' method which attempts to return a string decoded to uft8 Signed-off-by: Noel Power --- lib/ldb/pyldb.c | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c index 110ec8e60ad..8578821db16 100644 --- a/lib/ldb/pyldb.c +++ b/lib/ldb/pyldb.c @@ -79,6 +79,7 @@ static struct ldb_message_element *PyObject_AsMessageElement( PyObject *set_obj, unsigned int flags, const char *attr_name); +static PyTypeObject PyLdbBytesType; #if PY_MAJOR_VERSION >= 3 #define PyStr_Check PyUnicode_Check @@ -89,6 +90,16 @@ static struct ldb_message_element *PyObject_AsMessageElement( #define PyStr_AsUTF8 PyUnicode_AsUTF8 #define PyStr_AsUTF8AndSize PyUnicode_AsUTF8AndSize #define PyInt_FromLong PyLong_FromLong + +static PyObject *PyLdbBytes_FromStringAndSize(const char *msg, int size) +{ + PyObject* result = NULL; + PyObject* args = NULL; + args = Py_BuildValue("(y#)", msg, size); + result = PyLdbBytesType.tp_new(&PyLdbBytesType, args, NULL); + Py_DECREF(args); + return result; +} #else #define PyStr_Check PyString_Check #define PyStr_FromString PyString_FromString @@ -96,6 +107,7 @@ static struct ldb_message_element *PyObject_AsMessageElement( #define PyStr_FromFormat PyString_FromFormat #define PyStr_FromFormatV PyString_FromFormatV #define PyStr_AsUTF8 PyString_AsString +#define PyLdbBytes_FromStringAndSize PyString_FromStringAndSize const char *PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr); const char * @@ -270,6 +282,30 @@ static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ Py_BuildValue(discard_const_p(char, "(i,s)"), ret, ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx))); } +static PyObject *py_ldb_bytes_str(PyBytesObject *self) +{ + char *msg = NULL; + Py_ssize_t size; + int result = 0; + if (!PyBytes_Check(self)) { + PyErr_Format(PyExc_TypeError,"Unexpected type"); + return NULL; + } + result = PyBytes_AsStringAndSize((PyObject *)self, &msg, &size); + if (result != 0) { + PyErr_Format(PyExc_TypeError, "Failed to extract bytes"); + return NULL; + } + return PyUnicode_FromStringAndSize(msg, size); +} + +static PyTypeObject PyLdbBytesType = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "ldb.bytes", + .tp_doc = "str/bytes (with custom str)", + .tp_str = (reprfunc)py_ldb_bytes_str, + .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, +}; static PyObject *PyObject_FromLdbValue(const struct ldb_val *val) { @@ -2990,7 +3026,7 @@ static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssi PyErr_SetString(PyExc_IndexError, "Out of range"); return NULL; } - return PyBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length); + return PyLdbBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length); } static PySequenceMethods py_ldb_msg_element_seq = { @@ -4123,6 +4159,10 @@ static PyObject* module_init(void) { PyObject *m; + PyLdbBytesType.tp_base = &PyBytes_Type; + if (PyType_Ready(&PyLdbBytesType) < 0) + return NULL; + if (PyType_Ready(&PyLdbDn) < 0) return NULL; From 45660a8cd0b17d1f59b8fc695348e6f43dc88f00 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 16 May 2018 09:28:43 +0100 Subject: [PATCH 090/122] REWORK: post attribute as subclass as byte patch Previous patch in this branch returns a subclass of bytes for attributes that are part of Ldb.MessageElement. #FIXME the whole patch series needs to be reexamined as possibly many .decodes (or even other strings defined as 'b') might need to be redone. --- python/samba/tests/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samba/tests/core.py b/python/samba/tests/core.py index 504d458b7f8..a07dca80217 100644 --- a/python/samba/tests/core.py +++ b/python/samba/tests/core.py @@ -72,7 +72,7 @@ def test_searchone(self): l = samba.Ldb(path) try: l.add({"dn": "foo=dc", "bar": "bla"}) - self.assertEquals(b"bla", + self.assertEquals("bla", l.searchone(basedn=ldb.Dn(l, "foo=dc"), attribute="bar")) finally: del l From a97bcb769e9db54bd2307ee66489d0f0884d9164 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 11 May 2018 16:37:44 +0100 Subject: [PATCH 091/122] python/samba/tests: py2/py3 port has_keys usage Signed-off-by: Noel Power --- python/samba/tests/upgradeprovisionneeddc.py | 2 +- python/samba/upgradehelpers.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/samba/tests/upgradeprovisionneeddc.py b/python/samba/tests/upgradeprovisionneeddc.py index bf254531510..21c08ab4218 100644 --- a/python/samba/tests/upgradeprovisionneeddc.py +++ b/python/samba/tests/upgradeprovisionneeddc.py @@ -91,7 +91,7 @@ def test_search_constructed_attrs_stored(self): hashAtt = search_constructed_attrs_stored(self.ldbs.sam, self.names.rootdn, ["msds-KeyVersionNumber"]) - self.assertFalse(hashAtt.has_key("msds-KeyVersionNumber")) + self.assertFalse("msds-KeyVersionNumber" in hashAtt) def test_increment_calculated_keyversion_number(self): dn = "CN=Administrator,CN=Users,%s" % self.names.rootdn diff --git a/python/samba/upgradehelpers.py b/python/samba/upgradehelpers.py index 14fe3e024c3..5e5655d74a2 100644 --- a/python/samba/upgradehelpers.py +++ b/python/samba/upgradehelpers.py @@ -489,7 +489,7 @@ def increment_calculated_keyversion_number(samdb, rootdn, hashDns): raise ProvisioningError("Unable to find msDs-KeyVersionNumber") else: for e in entry: - if hashDns.has_key(str(e.dn).lower()): + if str(e.dn).lower() in hashDns: val = e.get("msDs-KeyVersionNumber") if not val: val = "0" @@ -689,7 +689,7 @@ def search_constructed_attrs_stored(samdb, rootdn, attrs): for ent in entry: for att in attrs: if ent.get(att): - if hashAtt.has_key(att): + if att in hashAtt: hashAtt[att][str(ent.dn).lower()] = str(ent[att]) else: hashAtt[att] = {} From 216935ed6a4b7deefda1f51a6e78763aab3a875c Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 11 May 2018 16:39:06 +0100 Subject: [PATCH 092/122] s4/selftest: enable samba.tests.upgradeprovisionneeddc for py3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index f55da63f9ef..bf96249d285 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -837,7 +837,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex extra_path=[os.path.join(samba4srcdir, 'dsdb/tests/python')], py3_compatible=True ) -planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.upgradeprovisionneeddc") +planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.upgradeprovisionneeddc", py3_compatible=True) planpythontestsuite("ad_dc:local", "samba.tests.posixacl", py3_compatible=True) planpythontestsuite("ad_dc_no_nss:local", "samba.tests.posixacl", py3_compatible=True) plantestsuite_loadlist("samba4.deletetest.python(ad_dc_ntvfs)", "ad_dc_ntvfs", [python, os.path.join(samba4srcdir, "dsdb/tests/python/deletetest.py"), From e6b198964e91607b4d34e14822298e4adfd7fb6c Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 11 May 2018 16:41:44 +0100 Subject: [PATCH 093/122] s4/selftest: enable samba.tests.samba_tool.rodc Note: seems this test is skipped so more than likely this enablement is meaningless --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index bf96249d285..8559f67b34a 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -870,7 +870,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex plansmbtorture4testsuite('rpc.echo', "%s:local" % env, ['ncacn_np:$SERVER', "-k", "no", '-Utestdenied%$DC_PASSWORD', '--workgroup=$DOMAIN'], modname="samba4.rpc.echo.testdenied") plantestsuite("samba4.blackbox.smbclient(%s:local)" % env, "%s:local" % env, [os.path.join(samba4srcdir, "utils/tests/test_smbclient.sh"), '$SERVER', '$SERVER_IP', '$USERNAME', '$PASSWORD', '$DOMAIN', smbclient4]) -planpythontestsuite("rodc:local", "samba.tests.samba_tool.rodc") +planpythontestsuite("rodc:local", "samba.tests.samba_tool.rodc", py3_compatible=True) plantestsuite("samba.blackbox.rpcclient_samlogon", "rodc:local", [os.path.join(samba3srcdir, "script/tests/test_rpcclient_samlogon.sh"), "$DC_USERNAME", "$DC_PASSWORD", "ncacn_np:$SERVER", configuration]) From 516842bd2143183769f79386d1502da5de2f5bd5 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 14 May 2018 20:03:59 +0100 Subject: [PATCH 094/122] s4/param: py2/p3 compat override_prefixmap should be string/bytes --- source4/param/provision.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/param/provision.c b/source4/param/provision.c index 4dab31f5c20..153850667b1 100644 --- a/source4/param/provision.c +++ b/source4/param/provision.c @@ -377,7 +377,7 @@ struct ldb_context *provision_get_schema(TALLOC_CTX *mem_ctx, if (override_prefixmap) { PyDict_SetItemString(parameters, "override_prefixmap", - PyStr_FromStringAndSize((const char *)override_prefixmap->data, + PyBytes_FromStringAndSize((const char *)override_prefixmap->data, override_prefixmap->length)); } From 01696fe6595175544ad069b556d4a54664c8030c Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 14 May 2018 20:05:30 +0100 Subject: [PATCH 095/122] s4/dsdb: py_dsdb_DsReplicaAttribute should deal with bytes in py3 Seems the underlying c code expects binary blob, so.. we should handle str for py2 and byte for py3 Signed-off-by: Noel Power --- source4/dsdb/pydsdb.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/source4/dsdb/pydsdb.c b/source4/dsdb/pydsdb.c index d9177bbd1d7..56786cc77d8 100644 --- a/source4/dsdb/pydsdb.c +++ b/source4/dsdb/pydsdb.c @@ -518,7 +518,6 @@ 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; @@ -580,13 +579,17 @@ 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 (!(PyStr_Check(item) || PyUnicode_Check(item))) { - PyErr_Format(PyExc_TypeError, "ldif_elements should be strings"); + if (!(PyBytes_Check(item))) { + PyErr_Format(PyExc_TypeError, + "ldif_element type should be " + PY_DESC_PY3_BYTES + ); talloc_free(tmp_ctx); return NULL; } - el->values[i].data = (uint8_t *)PyStr_AsUTF8AndSize(item, &_size); - el->values[i].length = _size; + el->values[i].data = + (uint8_t *)PyBytes_AsString(item); + el->values[i].length = PyBytes_Size(item); } } From 24bbc80e5c3ecfc54c4cbc9b9f2b63f2b9f77bee Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 17 May 2018 13:34:00 +0100 Subject: [PATCH 096/122] fallout from py_dsdb_DsReplicaAttribute to -> bytes Signed-off-by: Noel Power --- python/samba/join.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/samba/join.py b/python/samba/join.py index ff8d18a27fd..b04e5a74e2c 100644 --- a/python/samba/join.py +++ b/python/samba/join.py @@ -43,6 +43,7 @@ import talloc import random import time +from samba.compat import text_type class DCJoinException(Exception): @@ -488,6 +489,7 @@ def DsAddEntry(ctx, recs): v = [rec[a]] else: v = rec[a] + v = [x.encode('utf8') if isinstance(x, text_type) else x for x in v] rattr = ctx.tmp_samdb.dsdb_DsReplicaAttribute(ctx.tmp_samdb, a, v) attrs.append(rattr) From 16436ea304d7fe93a1791bad49b6bd208380d912 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 15 May 2018 09:29:04 +0100 Subject: [PATCH 097/122] python/samba: Py2/Py3 Fix exception list access (use args) --- python/samba/drs_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samba/drs_utils.py b/python/samba/drs_utils.py index 1940d2d1b27..1810ed8e7dd 100644 --- a/python/samba/drs_utils.py +++ b/python/samba/drs_utils.py @@ -319,7 +319,7 @@ def replicate(self, dn, source_dsa_invocation_id, destination_dsa_guid, schema=schema, req_level=req_level, req=req) except WERRORError as e: # Check if retrying with the GET_TGT flag set might resolve this error - if self._should_retry_with_get_tgt(e[0], req): + if self._should_retry_with_get_tgt(e.args[0], req): print("Missing target object - retrying with DRS_GET_TGT") req.more_flags |= drsuapi.DRSUAPI_DRS_GET_TGT From 35bf6af5684e63fae90faad9a47eabcaa8f3fe05 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 15 May 2018 15:28:48 +0100 Subject: [PATCH 098/122] python/samba: fix various attribute usage re py2/py3 compat Signed-off-by: Noel Power --- python/samba/dbchecker.py | 22 +++++++++++----------- python/samba/remove_dc.py | 6 +++--- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py index 5e486c41d33..df4378f3356 100644 --- a/python/samba/dbchecker.py +++ b/python/samba/dbchecker.py @@ -34,6 +34,7 @@ from samba.auth import system_session, admin_session from samba.netcmd import CommandError from samba.netcmd.fsmo import get_fsmo_roleowner +from samba.compat import text_type class dbcheck(object): @@ -1426,7 +1427,7 @@ def process_metadata(self, dn, val): list_attid = [] in_schema_nc = dn.is_child_of(self.schema_dn) - repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob, str(val)) + repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob, val) obj = repl.ctr for o in repl.ctr.array: @@ -1496,7 +1497,7 @@ def process_sd(self, dn, obj): sd_attr = "nTSecurityDescriptor" sd_val = obj[sd_attr] - sd = ndr_unpack(security.descriptor, str(sd_val)) + sd = ndr_unpack(security.descriptor, sd_val[0]) is_deleted = 'isDeleted' in obj and obj['isDeleted'][0].upper() == 'TRUE' if is_deleted: @@ -1670,7 +1671,7 @@ def err_missing_sd_owner(self, dn, sd): def has_replmetadata_zero_invocationid(self, dn, repl_meta_data): repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob, - str(repl_meta_data)) + repl_meta_data) ctr = repl.ctr found = False for o in ctr.array: @@ -1691,7 +1692,7 @@ def has_replmetadata_zero_invocationid(self, dn, repl_meta_data): def err_replmetadata_zero_invocationid(self, dn, attr, repl_meta_data): repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob, - str(repl_meta_data)) + repl_meta_data) ctr = repl.ctr now = samba.unix2nttime(int(time.time())) found = False @@ -1940,9 +1941,8 @@ def calculate_instancetype(self, dn): else: instancetype |= dsdb.INSTANCE_TYPE_NC_ABOVE - if self.write_ncs is not None and str(nc_root) in self.write_ncs: + if self.write_ncs is not None and str(nc_root) in [text_type(x, encoding='utf8') for x in self.write_ncs]: instancetype |= dsdb.INSTANCE_TYPE_WRITE - return instancetype def get_wellknown_sd(self, dn): @@ -2061,17 +2061,17 @@ def check_object(self, dn, attrs=['*']): self.report("ERROR: Not fixing num_values(%d) for '%s' on '%s'" % (len(obj[attrname]), attrname, str(obj.dn))) else: - object_rdn_val = obj[attrname][0] + object_rdn_val = str(obj[attrname][0]) if str(attrname).lower() == 'isdeleted': - if obj[attrname][0] != "FALSE": + if obj[attrname][0].decode('utf8') != "FALSE": isDeleted = True if str(attrname).lower() == 'systemflags': systemFlags = int(obj[attrname][0]) if str(attrname).lower() == 'replpropertymetadata': - if self.has_replmetadata_zero_invocationid(dn, obj[attrname]): + if self.has_replmetadata_zero_invocationid(dn, obj[attrname][0]): error_count += 1 self.err_replmetadata_zero_invocationid(dn, attrname, obj[attrname]) # We don't continue, as we may also have other fixes for this attribute @@ -2079,7 +2079,7 @@ def check_object(self, dn, attrs=['*']): try: (set_attrs_from_md, list_attid_from_md, wrong_attids) \ - = self.process_metadata(dn, obj[attrname]) + = self.process_metadata(dn, obj[attrname][0]) except KeyError: error_count += 1 self.err_replmetadata_unknown_attid(dn, attrname, obj[attrname]) @@ -2239,7 +2239,7 @@ def check_object(self, dn, attrs=['*']): if str(attrname).lower() == "instancetype": calculated_instancetype = self.calculate_instancetype(dn) - if len(obj["instanceType"]) != 1 or obj["instanceType"][0] != str(calculated_instancetype): + if len(obj["instanceType"]) != 1 or obj["instanceType"][0].decode('utf8') != str(calculated_instancetype): error_count += 1 self.err_wrong_instancetype(obj, calculated_instancetype) diff --git a/python/samba/remove_dc.py b/python/samba/remove_dc.py index 7cff234c61e..2541418aa51 100644 --- a/python/samba/remove_dc.py +++ b/python/samba/remove_dc.py @@ -218,7 +218,7 @@ def offline_remove_server(samdb, logger, res = samdb.search("", scope=ldb.SCOPE_BASE, attrs=["dsServiceName"]) assert len(res) == 1 - my_serviceName = res[0]["dsServiceName"][0] + my_serviceName = res[0]["dsServiceName"][0].decode('utf8') # Confirm this is really a server object msgs = samdb.search(base=server_dn, @@ -235,7 +235,7 @@ def offline_remove_server(samdb, logger, computer_dn = None try: - dnsHostName = msgs[0]["dnsHostName"][0] + dnsHostName = msgs[0]["dnsHostName"][0].decode('utf8') except KeyError: dnsHostName = None @@ -265,7 +265,7 @@ def offline_remove_server(samdb, logger, samdb.delete(computer_dn, ["tree_delete:0"]) if "dnsHostName" in msgs[0]: - dnsHostName = msgs[0]["dnsHostName"][0] + dnsHostName = msgs[0]["dnsHostName"][0].decode('utf8') if remove_dns_account: res = samdb.search(expression="(&(objectclass=user)(cn=dns-%s)(servicePrincipalName=DNS/%s))" % From 6b7a93e69214ca14602b468397a55a2f0cb2de9f Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 15 May 2018 15:32:35 +0100 Subject: [PATCH 099/122] s4/torture/drs/python: Py2/Py2 fix tab/space also incorrect unicode usage Signed-off-by: Noel Power --- source4/torture/drs/python/drs_base.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source4/torture/drs/python/drs_base.py b/source4/torture/drs/python/drs_base.py index a6a2439c457..c9518ef7358 100644 --- a/source4/torture/drs/python/drs_base.py +++ b/source4/torture/drs/python/drs_base.py @@ -268,11 +268,11 @@ def _ctr6_debug(self, ctr6): print("Link Tgt %s... <-- Src %s" %(target.dn[:25], l.identifier.guid)) - state = "Del" - if l.flags & drsuapi.DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE: - state = "Act" - print(" v%u %s changed %u" %(l.meta_data.version, state, - l.meta_data.originating_change_time)) + state = "Del" + if l.flags & drsuapi.DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE: + state = "Act" + print(" v%u %s changed %u" %(l.meta_data.version, state, + l.meta_data.originating_change_time)) print("HWM: %d" %(ctr6.new_highwatermark.highest_usn)) print("Tmp HWM: %d" %(ctr6.new_highwatermark.tmp_highest_usn)) @@ -424,7 +424,7 @@ def _exop_req8(self, dest_dsa, invocation_id, nc_dn_str, exop, req8.destination_dsa_guid = misc.GUID(dest_dsa) if dest_dsa else misc.GUID() req8.source_dsa_invocation_id = misc.GUID(invocation_id) req8.naming_context = drsuapi.DsReplicaObjectIdentifier() - req8.naming_context.dn = unicode(nc_dn_str) + req8.naming_context.dn = str(nc_dn_str) req8.highwatermark = drsuapi.DsReplicaHighWaterMark() req8.highwatermark.tmp_highest_usn = 0 req8.highwatermark.reserved_usn = 0 @@ -454,7 +454,7 @@ def _getnc_req10(self, dest_dsa, invocation_id, nc_dn_str, exop, req10.destination_dsa_guid = misc.GUID(dest_dsa) if dest_dsa else misc.GUID() req10.source_dsa_invocation_id = misc.GUID(invocation_id) req10.naming_context = drsuapi.DsReplicaObjectIdentifier() - req10.naming_context.dn = unicode(nc_dn_str) + req10.naming_context.dn = str(nc_dn_str) req10.highwatermark = drsuapi.DsReplicaHighWaterMark() req10.highwatermark.tmp_highest_usn = 0 req10.highwatermark.reserved_usn = 0 From 02883fe63f85be373418a19d54029663c56da3b9 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 15 May 2018 15:33:22 +0100 Subject: [PATCH 100/122] s4/selftest: enable samba4.drs.ridalloc_exop for python3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 8559f67b34a..f78ea28c3a2 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -895,7 +895,8 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex extra_path=[os.path.join(samba4srcdir, 'torture/drs/python')], name="samba4.drs.ridalloc_exop.python(%s)" % env, environ={'DC1': "$DC_SERVER", 'DC2': '$%s_SERVER' % env.upper()}, - extra_args=['-U$DOMAIN/$DC_USERNAME%$DC_PASSWORD']) + extra_args=['-U$DOMAIN/$DC_USERNAME%$DC_PASSWORD'], + py3_compatible=True) for env in ['vampire_dc', 'promoted_dc']: planoldpythontestsuite("%s:local" % env, "samba_tool_drs", From 7c46584276d72d589838e6f8f14e4c456d8f4b49 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 16 May 2018 15:01:04 +0100 Subject: [PATCH 101/122] REWORK (after bytes fix subclass ) *I Think* Signed-off-by: Noel Power --- python/samba/dbchecker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py index df4378f3356..ee5676d6241 100644 --- a/python/samba/dbchecker.py +++ b/python/samba/dbchecker.py @@ -2073,7 +2073,7 @@ def check_object(self, dn, attrs=['*']): if str(attrname).lower() == 'replpropertymetadata': if self.has_replmetadata_zero_invocationid(dn, obj[attrname][0]): error_count += 1 - self.err_replmetadata_zero_invocationid(dn, attrname, obj[attrname]) + self.err_replmetadata_zero_invocationid(dn, attrname, obj[attrname][0]) # We don't continue, as we may also have other fixes for this attribute # based on what other attributes we see. From 114aa16d3173f4ee0acf53b77d680379a27683ae Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 17 May 2018 15:23:38 +0100 Subject: [PATCH 102/122] python/samba/netcmd: fix py2/py3 bytes usage for replace base64.b64encode returns bytes in py3 make sure associated replace uses 'b' for strings passed to replace Signed-off-by: Noel Power --- python/samba/netcmd/user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samba/netcmd/user.py b/python/samba/netcmd/user.py index 38487f7273a..fb5c487680e 100644 --- a/python/samba/netcmd/user.py +++ b/python/samba/netcmd/user.py @@ -119,7 +119,7 @@ def get_crypt_value(alg, utf8pw, rounds=0): # we can ignore the possible == at the end # of the base64 string # we just need to replace '+' by '.' - b64salt = base64.b64encode(salt)[0:16].replace('+', '.').decode('utf8') + b64salt = base64.b64encode(salt)[0:16].replace(b'+', b'.').decode('utf8') crypt_salt = "" if rounds != 0: crypt_salt = "$%s$rounds=%s$%s$" % (alg, rounds, b64salt) From bf1a2b4a575648a6537550b84d0c89d2db9951c1 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 17 May 2018 15:25:29 +0100 Subject: [PATCH 103/122] python/samba/netcmd: Protect variable that can be None In py3 None variable cannot be compared with '>' '<' etc operators Signed-off-by: Noel Power --- python/samba/netcmd/domain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samba/netcmd/domain.py b/python/samba/netcmd/domain.py index 7142871c5c8..3c5a7df046f 100644 --- a/python/samba/netcmd/domain.py +++ b/python/samba/netcmd/domain.py @@ -1522,7 +1522,7 @@ def run(self, H=None, min_pwd_age=None, max_pwd_age=None, ldb.FLAG_MOD_REPLACE, "lockOutObservationWindow") msgs.append("Duration to reset account lockout after changed!") - if max_pwd_age > 0 and min_pwd_age >= max_pwd_age: + if max_pwd_age and max_pwd_age > 0 and min_pwd_age >= max_pwd_age: raise CommandError("Maximum password age (%d) must be greater than minimum password age (%d)!" % (max_pwd_age, min_pwd_age)) if len(m) == 0: From 6f264ff1df002cd074a59cb41dfafb17ae976fbe Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 17 May 2018 15:28:10 +0100 Subject: [PATCH 104/122] python/samba/tests/samba_tool: Ensure test works for py3 self.ldb.get_minPwdLength() returns ldb.MessageElement item (e.g.) bytes (or maybe new LdbBytes subclass of bytes) we can either a) make get_minPwdLength() return unicode/str (py2/py3) b) just change the test comparison to either decode the attribute or use the str() function on the attribute (which will result in custom __str__ function getting called when running in PY3) choosing b at the moment Signed-off-by: Noel Power --- python/samba/tests/samba_tool/passwordsettings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samba/tests/samba_tool/passwordsettings.py b/python/samba/tests/samba_tool/passwordsettings.py index 7c1afc8f51b..99b42ca49f0 100644 --- a/python/samba/tests/samba_tool/passwordsettings.py +++ b/python/samba/tests/samba_tool/passwordsettings.py @@ -427,7 +427,7 @@ def test_domain_passwordsettings(self): self.assertCmdSuccess(result, out, err) self.assertEquals(err,"","Shouldn't be any error messages") self.assertIn("successful", out) - self.assertEquals(str(new_len), self.ldb.get_minPwdLength()) + self.assertEquals(str(new_len), str(self.ldb.get_minPwdLength())) # check the updated value is now displayed (result, out, err) = self.runsublevelcmd("domain", ("passwordsettings", From c6f10243dd8094b2593fe60f295b113c1f5b7ebe Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 17 May 2018 14:51:40 +0100 Subject: [PATCH 105/122] s4/selftest: enable samba.tests.samba_tool.passwordsetting for Py3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index f78ea28c3a2..ca08d04e9f7 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -624,7 +624,7 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planpythontestsuite("ad_dc:local", "samba.tests.samba_tool.ntacl", py3_compatible=True) planpythontestsuite("none", "samba.tests.samba_tool.provision_password_check", py3_compatible=True) planpythontestsuite("none", "samba.tests.samba_tool.help", py3_compatible=True) -planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.passwordsettings") +planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.passwordsettings", py3_compatible=True) # Run these against chgdcpass to share the runtime load planpythontestsuite("chgdcpass:local", "samba.tests.samba_tool.sites", py3_compatible=True) From 7bda07d9c10ee237a271bb7e9f92d0b4200d621c Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 17 May 2018 15:57:38 +0100 Subject: [PATCH 106/122] s4/selftest/tests.py enable samba.tests.getdcname for py3 --- source4/selftest/tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index ca08d04e9f7..e1d0adda264 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -688,7 +688,8 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planoldpythontestsuite("fl2008r2dc:local", "samba.tests.getdcname", - extra_args=['-U"$USERNAME%$PASSWORD"']) + extra_args=['-U"$USERNAME%$PASSWORD"'], + py3_compatible=True) planoldpythontestsuite("ad_dc", "samba.tests.net_join_no_spnego", From cadd85a5f752ac0f69a473fdc1d216b84db63da3 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 17 May 2018 16:02:48 +0100 Subject: [PATCH 107/122] python/samba/test: more Exception Tuple correction Signed-off-by: Noel Power --- python/samba/tests/net_join_no_spnego.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/samba/tests/net_join_no_spnego.py b/python/samba/tests/net_join_no_spnego.py index 09a2856c9b5..85c6f888d44 100644 --- a/python/samba/tests/net_join_no_spnego.py +++ b/python/samba/tests/net_join_no_spnego.py @@ -55,7 +55,7 @@ def test_net_join_no_spnego(self): self.domain, netbios_name, LIBNET_JOIN_AUTOMATIC, machinepass=machinepass) except NTSTATUSError as e: - code = ctypes.c_uint32(e[0]).value + code = ctypes.c_uint32(e.args[0]).value if code == ntstatus.NT_STATUS_CONNECTION_DISCONNECTED: self.fail("Connection failure") elif code == ntstatus.NT_STATUS_ACCESS_DENIED: @@ -82,7 +82,7 @@ def test_net_join_no_spnego_ntlmv1(self): self.domain, netbios_name, LIBNET_JOIN_AUTOMATIC, machinepass=machinepass) except NTSTATUSError as e: - code = ctypes.c_uint32(e[0]).value + code = ctypes.c_uint32(e.args[0]).value if code == ntstatus.NT_STATUS_CONNECTION_DISCONNECTED: self.fail("Connection failure") raise From 24769d7a3bb51f3309a0124f7cc13c066649d40c Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 17 May 2018 16:06:19 +0100 Subject: [PATCH 108/122] s4/selftest: enable samba.tests.net_join_no_spnego for py3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index e1d0adda264..ea7b054ddd2 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -693,7 +693,8 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planoldpythontestsuite("ad_dc", "samba.tests.net_join_no_spnego", - extra_args=['-U"$USERNAME%$PASSWORD"']) + extra_args=['-U"$USERNAME%$PASSWORD"'], + py3_compatible=True) planoldpythontestsuite("ad_dc", "samba.tests.net_join", extra_args=['-U"$USERNAME%$PASSWORD"']) From 0ddedeb8afb3979d8f6b868c740ae4b999eade85 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 17 May 2018 19:26:06 +0100 Subject: [PATCH 109/122] FIXUP: after rejigging patches to get tombstone_reanimation working again --- source4/dsdb/tests/python/tombstone_reanimation.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/source4/dsdb/tests/python/tombstone_reanimation.py b/source4/dsdb/tests/python/tombstone_reanimation.py index 6185922dcf5..80c26147960 100755 --- a/source4/dsdb/tests/python/tombstone_reanimation.py +++ b/source4/dsdb/tests/python/tombstone_reanimation.py @@ -31,6 +31,7 @@ from samba.dcerpc import drsblobs from samba.dcerpc.drsuapi import * from samba.tests.password_test import PasswordCommon +from samba.compat import text_type import samba.tests from ldb import (SCOPE_BASE, FLAG_MOD_ADD, FLAG_MOD_DELETE, FLAG_MOD_REPLACE, Dn, Message, @@ -58,7 +59,7 @@ def tearDown(self): super(RestoredObjectAttributesBaseTestCase, self).tearDown() def GUID_string(self, guid): - return self.samdb.schema_format_value("objectGUID", guid) + return self.samdb.schema_format_value("objectGUID", guid).decode('utf8') def search_guid(self, guid, attrs=["*"]): res = self.samdb.search(base="" % self.GUID_string(guid), @@ -129,12 +130,18 @@ def assertAttributesExists(self, attr_expected, obj_msg): if expected_val == "**": # "**" values means "any" continue - self.assertEqual(expected_val, str(actual_val), + # if expected_val is e.g. ldb.bytes we can't depend on str(actual_value) + # working, we may just get a decoding error. Just compare raw values + if not isinstance(expected_val, str): + actual_val = actual_val[0] + else: + actual_val = str(actual_val) + self.assertEqual(expected_val, actual_val, "Unexpected value (%s) for '%s', expected (%s)" % ( - str(actual_val), name, expected_val)) + repr(actual_val), name, repr(expected_val))) def _check_metadata(self, metadata, expected): - repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob, str(metadata[0])) + repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob, metadata[0]) repl_array = [] for o in repl.ctr.array: @@ -261,7 +268,7 @@ def test_undelete_with_mod(self): objDeleted1 = self.search_guid(guid1) self.restore_deleted_object(self.samdb, objDeleted1.dn, usr1, {"url": "www.samba.org"}) objLive2 = self.search_dn(usr1) - self.assertEqual(objLive2["url"][0], "www.samba.org") + self.assertEqual(objLive2["url"][0], b"www.samba.org") samba.tests.delete_force(self.samdb, usr1) def test_undelete_newuser(self): From a6656116af29e519e681c14b8674e07f403c7cac Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 17 May 2018 21:24:13 +0100 Subject: [PATCH 110/122] REWORK another fallout from ldb.bytes (for attributes) Signed-off-by: Noel Power --- python/samba/tests/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samba/tests/core.py b/python/samba/tests/core.py index a07dca80217..504d458b7f8 100644 --- a/python/samba/tests/core.py +++ b/python/samba/tests/core.py @@ -72,7 +72,7 @@ def test_searchone(self): l = samba.Ldb(path) try: l.add({"dn": "foo=dc", "bar": "bla"}) - self.assertEquals("bla", + self.assertEquals(b"bla", l.searchone(basedn=ldb.Dn(l, "foo=dc"), attribute="bar")) finally: del l From cd90f35b82116b5d025d089b3a6037baaf6b3c77 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 18 May 2018 12:12:44 +0100 Subject: [PATCH 111/122] python/samba/netcmd: Fix relative module import Part of changes needed to enabled samba4.drs.replica_sync_rodc Signed-off-by: Noel Power --- python/samba/netcmd/drs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samba/netcmd/drs.py b/python/samba/netcmd/drs.py index 9b3c6050af9..72e0be0caa9 100644 --- a/python/samba/netcmd/drs.py +++ b/python/samba/netcmd/drs.py @@ -22,7 +22,7 @@ import samba.getopt as options import ldb import logging -import common +from . import common from samba.auth import system_session from samba.netcmd import ( From 0e14f0e594f41d7a9ba85512647b5ad086032994 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 18 May 2018 12:15:15 +0100 Subject: [PATCH 112/122] python/samba: Py2/Py3 compat changes byte/str -> unicode/str Part of changes needed to enabled samba4.drs.replica_sync_rodc Signed-off-by: Noel Power --- python/samba/drs_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samba/drs_utils.py b/python/samba/drs_utils.py index 1810ed8e7dd..12d803a4dd1 100644 --- a/python/samba/drs_utils.py +++ b/python/samba/drs_utils.py @@ -165,7 +165,7 @@ def drs_get_rodc_partial_attribute_set(samdb): "searchFlags"]) for r in res: - ldap_display_name = r["lDAPDisplayName"][0] + ldap_display_name = r["lDAPDisplayName"][0].decode('utf8') if "systemFlags" in r: system_flags = r["systemFlags"][0] if (int(system_flags) & (samba.dsdb.DS_FLAG_ATTR_NOT_REPLICATED | From 12288550582cfcaf4ed48eec0ba7101dac62ac3b Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 18 May 2018 12:16:05 +0100 Subject: [PATCH 113/122] s4/torture/drs/pythons: Py2/Py3 compat changes byte/str -> unicode/str Part of changes needed to enabled samba4.drs.replica_sync_rodc Signed-off-by: Noel Power --- source4/torture/drs/python/drs_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/torture/drs/python/drs_base.py b/source4/torture/drs/python/drs_base.py index c9518ef7358..41c754396f3 100644 --- a/source4/torture/drs/python/drs_base.py +++ b/source4/torture/drs/python/drs_base.py @@ -83,7 +83,7 @@ def set_test_ldb_dc(self, ldb_dc): self.test_ldb_dc = ldb_dc def _GUID_string(self, guid): - return self.test_ldb_dc.schema_format_value("objectGUID", guid) + return self.test_ldb_dc.schema_format_value("objectGUID", guid).decode('utf8') def _ldap_schemaUpdateNow(self, sam_db): rec = {"dn": "", From aab28b85b8584f1f1f5de56fa1577d040de945f3 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 18 May 2018 12:35:21 +0100 Subject: [PATCH 114/122] s4/selftest: enable samba.tests.net_join for py3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index ea7b054ddd2..d85730d8bfc 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -697,7 +697,8 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex py3_compatible=True) planoldpythontestsuite("ad_dc", "samba.tests.net_join", - extra_args=['-U"$USERNAME%$PASSWORD"']) + extra_args=['-U"$USERNAME%$PASSWORD"'], + py3_compatible=True) # Need to test the password hashing in multiple environments to ensure that # all the possible options are covered # From fb024ddf430742b2319e04a351ef645a9f5bbdfa Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 18 May 2018 12:43:22 +0100 Subject: [PATCH 115/122] s4/selftest: enable samba4.ldap.password_settings for py3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index d85730d8bfc..9f1df5d4d71 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -816,7 +816,8 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex planoldpythontestsuite("ad_dc_ntvfs", "password_settings", extra_path=[os.path.join(samba4srcdir, 'dsdb/tests/python')], name="samba4.ldap.password_settings.python", - extra_args=['-U$DOMAIN/$DC_USERNAME%$DC_PASSWORD']) + extra_args=['-U$DOMAIN/$DC_USERNAME%$DC_PASSWORD'], + py3_compatible=True) for env in ["ad_dc_ntvfs", "fl2000dc", "fl2003dc", "fl2008r2dc"]: plantestsuite_loadlist("samba4.ldap_schema.python(%s)" % env, env, [python, os.path.join(samba4srcdir, "dsdb/tests/python/ldap_schema.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '$LOADLIST', '$LISTOPT']) From 44755c64a1474ec6959944afa0b4556d1874b8c5 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 18 May 2018 16:14:39 +0100 Subject: [PATCH 116/122] s4/torture/drs: port samba4.drs.samba_tool_drs for py2/py3 compat Signed-off-by: Noel Power --- source4/torture/drs/python/samba_tool_drs.py | 57 +++++++++++++++------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/source4/torture/drs/python/samba_tool_drs.py b/source4/torture/drs/python/samba_tool_drs.py index 502c8096603..774a1229c54 100644 --- a/source4/torture/drs/python/samba_tool_drs.py +++ b/source4/torture/drs/python/samba_tool_drs.py @@ -38,6 +38,7 @@ def setUp(self): creds.get_username(), creds.get_password()) def tearDown(self): + db = self.getSamDB("-H", "ldap://%s" % (self.dc1), self.cmdline_creds) self._enable_inbound_repl(self.dnsname_dc1) self._enable_inbound_repl(self.dnsname_dc2) @@ -47,6 +48,8 @@ def tearDown(self): shutil.rmtree(os.path.join(self.tempdir, "msg.lock")) os.remove(os.path.join(self.tempdir, "names.tdb")) shutil.rmtree(os.path.join(self.tempdir, "state")) + db.deletegroup("group-repl-local-%s" % self.dc2) + db.deleteuser("user-repl-local-%s" % self.dc2) except Exception: pass @@ -68,8 +71,8 @@ def test_samba_tool_bind(self): # Repl epoch: 0 out = self.check_output("samba-tool drs bind %s %s" % (self.dc1, self.cmdline_creds)) - self.assertTrue("Site GUID:" in out) - self.assertTrue("Repl epoch:" in out) + self.assertTrue("Site GUID:" in out.decode('utf8')) + self.assertTrue("Repl epoch:" in out.decode('utf8')) def test_samba_tool_kcc(self): """Tests 'samba-tool drs kcc' command.""" @@ -77,8 +80,8 @@ def test_samba_tool_kcc(self): # Output should be like 'Consistency check on successful.' out = self.check_output("samba-tool drs kcc %s %s" % (self.dc1, self.cmdline_creds)) - self.assertTrue("Consistency check on" in out) - self.assertTrue("successful" in out) + self.assertTrue(b"Consistency check on" in out) + self.assertTrue(b"successful" in out) def test_samba_tool_options(self): """Tests 'samba-tool drs options' command @@ -86,7 +89,7 @@ def test_samba_tool_options(self): # Output should be like 'Current DSA options: IS_GC ' out = self.check_output("samba-tool drs options %s %s" % (self.dc1, self.cmdline_creds)) - self.assertTrue("Current DSA options:" in out) + self.assertTrue(b"Current DSA options:" in out) def test_samba_tool_replicate(self): """Tests 'samba-tool drs replicate' command.""" @@ -97,8 +100,8 @@ def test_samba_tool_replicate(self): self.dc2, nc_name, self.cmdline_creds)) - self.assertTrue("Replicate from" in out) - self.assertTrue("was successful" in out) + self.assertTrue(b"Replicate from" in out) + self.assertTrue(b"was successful" in out) def test_samba_tool_replicate_async(self): """Tests 'samba-tool drs replicate --async-op' command.""" @@ -109,8 +112,8 @@ def test_samba_tool_replicate_async(self): self.dc2, nc_name, self.cmdline_creds)) - self.assertTrue("Replicate from" in out) - self.assertTrue("was started" in out) + self.assertTrue(b"Replicate from" in out) + self.assertTrue(b"was started" in out) def test_samba_tool_replicate_local_online(self): """Tests 'samba-tool drs replicate --local-online' command.""" @@ -120,8 +123,8 @@ def test_samba_tool_replicate_local_online(self): out = self.check_output("samba-tool drs replicate --local-online %s %s %s" % (self.dc1, self.dc2, nc_name)) - self.assertTrue("Replicate from" in out) - self.assertTrue("was successful" in out) + self.assertTrue(b"Replicate from" in out) + self.assertTrue(b"was successful" in out) def test_samba_tool_replicate_local_online_async(self): """Tests 'samba-tool drs replicate --local-online --async-op' command.""" @@ -131,8 +134,8 @@ def test_samba_tool_replicate_local_online_async(self): out = self.check_output("samba-tool drs replicate --local-online --async-op %s %s %s" % (self.dc1, self.dc2, nc_name)) - self.assertTrue("Replicate from" in out) - self.assertTrue("was started" in out) + self.assertTrue(b"Replicate from" in out) + self.assertTrue(b"was started" in out) def test_samba_tool_replicate_local_machine_creds(self): """Tests 'samba-tool drs replicate --local -P' command (uses machine creds).""" @@ -142,8 +145,8 @@ def test_samba_tool_replicate_local_machine_creds(self): out = self.check_output("samba-tool drs replicate -P --local %s %s %s" % (self.dc1, self.dc2, nc_name)) - self.assertTrue("Incremental" in out) - self.assertTrue("was successful" in out) + self.assertTrue(b"Incremental" in out) + self.assertTrue(b"was successful" in out) def test_samba_tool_replicate_local(self): """Tests 'samba-tool drs replicate --local' command (uses machine creds).""" @@ -154,7 +157,7 @@ def test_samba_tool_replicate_local(self): def get_num_obj_links(output): num_objs = None num_links = None - for word in output.split(" "): + for word in output.decode('utf8').split(" "): try: int(word) if num_objs is None: @@ -168,15 +171,15 @@ def get_num_obj_links(output): out = self.check_output("samba-tool drs replicate --local --full-sync %s %s %s %s" % (self.dc1, self.dc2, nc_name, self.cmdline_creds)) - self.assertTrue("was successful" in out) - self.assertTrue("Full" in out) + self.assertTrue(b"was successful" in out) + self.assertTrue(b"Full" in out) (first_obj, _) = get_num_obj_links(out) out = self.check_output("samba-tool drs replicate --local %s %s %s %s" % (self.dc1, self.dc2, nc_name, self.cmdline_creds)) - self.assertTrue("was successful" in out) - self.assertTrue("Incremental" in out) + self.assertTrue(b"was successful" in out) + self.assertTrue(b"Incremental" in out) (second_obj, _) = get_num_obj_links(out) @@ -255,8 +258,8 @@ def test_samba_tool_replicate_machine_creds_P(self): out = self.check_output("samba-tool drs replicate -P %s %s %s" % (self.dc1, self.dc2, nc_name)) - self.assertTrue("Replicate from" in out) - self.assertTrue("was successful" in out) + self.assertTrue(b"Replicate from" in out) + self.assertTrue(b"was successful" in out) def test_samba_tool_replicate_machine_creds(self): """Tests 'samba-tool drs replicate' command with implicit machine creds.""" @@ -266,8 +269,8 @@ def test_samba_tool_replicate_machine_creds(self): out = self.check_output("samba-tool drs replicate %s %s %s" % (self.dc1, self.dc2, nc_name)) - self.assertTrue("Replicate from" in out) - self.assertTrue("was successful" in out) + self.assertTrue(b"Replicate from" in out) + self.assertTrue(b"was successful" in out) def test_samba_tool_drs_clone_dc(self): """Tests 'samba-tool drs clone-dc-database' command.""" @@ -297,8 +300,8 @@ def get_krbtgt_pw(): krbtgt_pw = samdb.searchone("unicodePwd", "cn=krbtgt,CN=users,%s" % nc_name) self.assertRaises(KeyError, get_krbtgt_pw) - server_dn = samdb.searchone("serverReferenceBL", "cn=%s,ou=domain controllers,%s" % (self.dc2, server_nc_name)) - ntds_guid = samdb.searchone("objectGUID", "cn=ntds settings,%s" % server_dn) + server_dn = samdb.searchone("serverReferenceBL", "cn=%s,ou=domain controllers,%s" % (self.dc2, server_nc_name)).decode('utf8') + ntds_guid = samdb.searchone("objectGUID", "cn=ntds settings,%s" % server_dn).decode('utf8') res = samdb.search(base=str(server_nc_name), expression="(&(objectclass=user)(cn=dns-%s))" % (self.dc2), @@ -362,7 +365,7 @@ def test_samba_tool_drs_clone_dc_secrets(self): self.assertEqual(ds_name, server_ds_name) self.assertEqual(ldap_service_name, server_ldap_service_name) - server_dn = samdb.searchone("serverReferenceBL", "cn=%s,ou=domain controllers,%s" % (self.dc2, server_nc_name)) + server_dn = samdb.searchone("serverReferenceBL", "cn=%s,ou=domain controllers,%s" % (self.dc2, server_nc_name)).decode('utf8') ntds_guid = samdb.searchone("objectGUID", "cn=ntds settings,%s" % server_dn) res = samdb.search(base=str(server_nc_name), From 294b1d3351c7099045f0fa2982e893c332400d38 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 18 May 2018 16:15:01 +0100 Subject: [PATCH 117/122] s4/selftest: enable samba4.drs.samba_tool_drs for py3 Signed-off-by: Noel Power --- source4/selftest/tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 9f1df5d4d71..8ef70138256 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -907,7 +907,8 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex extra_path=[os.path.join(samba4srcdir, 'torture/drs/python')], name="samba4.drs.samba_tool_drs.python(%s)" % env, environ={'DC1': '$DC_SERVER', 'DC2': '$%s_SERVER' % env.upper()}, - extra_args=['-U$DOMAIN/$DC_USERNAME%$DC_PASSWORD']) + extra_args=['-U$DOMAIN/$DC_USERNAME%$DC_PASSWORD'], + py3_compatible=True) planoldpythontestsuite("%s:local" % env, "samba_tool_drs_showrepl", extra_path=[os.path.join(samba4srcdir, 'torture/drs/python')], name="samba4.drs.samba_tool_drs_showrepl.python(%s)" % env, From 5afc185f04943a83497214bf095a6a97bc744f67 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Fri, 18 May 2018 17:15:44 +0100 Subject: [PATCH 118/122] s4/librpc/ndr: allow GUID to accept unicode also This needed since _GUID_string method change (in source4/torture/drs/python/drs_base.py) which makes use use a unicode guid at times now Signed-off-by: Noel Power --- source4/librpc/ndr/py_misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/librpc/ndr/py_misc.c b/source4/librpc/ndr/py_misc.c index 849a11460a4..6c0b8b2af14 100644 --- a/source4/librpc/ndr/py_misc.c +++ b/source4/librpc/ndr/py_misc.c @@ -97,7 +97,7 @@ static int py_GUID_init(PyObject *self, PyObject *args, PyObject *kwargs) DATA_BLOB guid_val; Py_ssize_t _size; - if (!IsPy3BytesOrString(str)) { + if (!IsPy3BytesOrString(str) && !PyUnicode_Check(str)) { PyErr_SetString(PyExc_TypeError, "Expected a string or bytes argument to GUID()"); return -1; } From bba21ef01b2e84532d92d6df403339398f3c52fa Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 23 May 2018 17:19:07 +0100 Subject: [PATCH 119/122] lib/autit_logging: squash valgrind warning ==6702== Conditional jump or move depends on uninitialised value(s) ==6702== at 0xD6EEF32: imessaging_send (messaging_send.c:68) ==6702== by 0xC189E42: audit_message_send (audit_logging.c:219) ==6702== by 0xC18875D: log_json (auth_log.c:100) ==6702== by 0xC188CC1: log_successful_authz_event_json (auth_log.c:281) ==6702== by 0xC18977A: log_successful_authz_event (auth_log.c:622) ==6702== by 0x6BA2888: log_successful_gensec_authz_event (gensec.c:239) ==6702== by 0x6BA2924: gensec_session_info (gensec.c:273) ==6702== by 0x1C3ACBE0: dcesrv_auth_complete (dcesrv_auth.c:277) ==6702== by 0x1C41AFA2: dcesrv_alter_done (dcerpc_server.c:1686) ==6702== by 0x6151736: _tevent_req_notify_callback (tevent_req.c:125) ==6702== by 0x615180B: tevent_req_finish (tevent_req.c:162) ==6702== by 0x6151833: _tevent_req_done (tevent_req.c:168) Signed-off-by: Noel Power --- lib/audit_logging/audit_logging.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/audit_logging/audit_logging.c b/lib/audit_logging/audit_logging.c index 5c16806d54e..ea868c208e6 100644 --- a/lib/audit_logging/audit_logging.c +++ b/lib/audit_logging/audit_logging.c @@ -194,7 +194,7 @@ void audit_message_send( uint32_t message_type, const char *message) { - struct server_id event_server; + struct server_id event_server = {}; NTSTATUS status; DATA_BLOB message_blob = data_blob_string_const(message); From 0227cfe3c01162132e059f76f01dd38dedcd99d0 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 31 May 2018 12:20:31 +0100 Subject: [PATCH 120/122] python/samba/tests/samba_tool: fix problems with visualize (post rebase) --- python/samba/tests/samba_tool/visualize.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/samba/tests/samba_tool/visualize.py b/python/samba/tests/samba_tool/visualize.py index 72703da039e..f4c6bb60c42 100644 --- a/python/samba/tests/samba_tool/visualize.py +++ b/python/samba/tests/samba_tool/visualize.py @@ -153,7 +153,8 @@ def test_import_ldif_xdot(self): '--color=no', '-S', '--xdot') - f = open(content) + from io import open as ioopen + f = ioopen(content) xdot = f.read() f.close() os.remove(fake_xdot) @@ -396,6 +397,7 @@ def test_dot_ntdsconn_disconnected_to_file(self): '--color=no', '-S', '--dot', '-o', dot_file) self.assertCmdSuccess(result, dot, err) + from io import open f = open(dot_file) dot = f.read() f.close() From d6fcd03b339bb256b7b02b72508633b5c6b92cf7 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 31 May 2018 14:30:43 +0100 Subject: [PATCH 121/122] python/samba/netcmd: fix samba.tests.samba_tool.passwordsettings post rebase some new tests have been added (and new py2/py3 issues) --- python/samba/netcmd/pso.py | 8 +++----- python/samba/tests/pso.py | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/python/samba/netcmd/pso.py b/python/samba/netcmd/pso.py index b12f00db071..70c22447db8 100644 --- a/python/samba/netcmd/pso.py +++ b/python/samba/netcmd/pso.py @@ -521,11 +521,9 @@ def run(self, psoname, H=None, credopts=None, sambaopts=None, self.message("Deleted PSO %s" % psoname) -def pso_cmp(a, b): - """Compares two PSO LDB search results""" +def pso_key(a): a_precedence = int(a['msDS-PasswordSettingsPrecedence'][0]) - b_precedence = int(b['msDS-PasswordSettingsPrecedence'][0]) - return a_precedence - b_precedence + return a_precedence class cmd_domain_pwdsettings_pso_list(Command): """Lists all Password Settings Objects (PSOs).""" @@ -561,7 +559,7 @@ def run(self, H=None, credopts=None, sambaopts=None, versionopts=None): return # sort the PSOs so they're displayed in order of precedence - pso_list = sorted(res, cmp=pso_cmp) + pso_list = sorted(res, key=pso_key) self.outf.write("Precedence | PSO name\n") self.outf.write("--------------------------------------------------\n") diff --git a/python/samba/tests/pso.py b/python/samba/tests/pso.py index 8ca86be5e80..b6720734ddc 100644 --- a/python/samba/tests/pso.py +++ b/python/samba/tests/pso.py @@ -84,7 +84,7 @@ def get_resultant_PSO(self): res = self.ldb.search(self.dn, attrs=['msDS-ResultantPSO']) if 'msDS-ResultantPSO' in res[0]: - return res[0]['msDS-ResultantPSO'][0] + return res[0]['msDS-ResultantPSO'][0].decode('utf8') else: return None From 194f437c628ebdd7d0b10c5c0f5efcb17ae99954 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 31 May 2018 16:13:28 +0100 Subject: [PATCH 122/122] s4/dsdb/tests/python: fix samba4.ldap.password_settings post rebase something changed and tests needed adjusting --- source4/dsdb/tests/python/password_settings.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source4/dsdb/tests/python/password_settings.py b/source4/dsdb/tests/python/password_settings.py index d072a8fa165..1cb220b88fc 100644 --- a/source4/dsdb/tests/python/password_settings.py +++ b/source4/dsdb/tests/python/password_settings.py @@ -727,7 +727,7 @@ def test_pso_add_user(self): # defaults, to prove that the DC will reject bad passwords during a # user add userdn = "CN=testuser,%s" % self.ou - password = base64.b64encode("\"abcdef\"".encode('utf-16-le')) + password = base64.b64encode("\"abcdef\"".encode('utf-16-le')).decode('utf8') # Note we use an LDIF operation to ensure that the password gets set # as part of the 'add' operation (whereas self.add_user() adds the user @@ -751,7 +751,7 @@ def test_pso_add_user(self): # now use a password that meets the domain defaults, but doesn't meet # the PSO requirements. Note that Windows allows this, i.e. it doesn't # honour the PSO during the add operation - password = base64.b64encode("\"abcde12#\"".encode('utf-16-le')) + password = base64.b64encode("\"abcde12#\"".encode('utf-16-le')).decode('utf8') ldif = """ dn: %s objectClass: user @@ -787,7 +787,7 @@ def test_pso_add_user(self): self.assertTrue('0000052D' in msg, msg) # check setting a password that meets the PSO settings works - password = base64.b64encode("\"abcdefghijkl\"".encode('utf-16-le')) + password = base64.b64encode("\"abcdefghijkl\"".encode('utf-16-le')).decode('utf8') ldif = """ dn: %s changetype: modify