From 536d24adefe184012fc9583e4b410d9417734874 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 10 Apr 2018 15:28:59 +0100 Subject: [PATCH 1/2] python/samba: Port to py3 code exercised by samba.tests.dsdb_lock Signed-off-by: Noel Power --- python/samba/__init__.py | 6 ++-- python/samba/dbchecker.py | 7 ++-- python/samba/descriptor.py | 2 +- python/samba/idmap.py | 2 +- python/samba/ms_display_specifiers.py | 3 +- python/samba/ms_schema.py | 11 +++--- python/samba/netcmd/fsmo.py | 2 +- python/samba/provision/__init__.py | 64 +++++++++++++++++++---------------- python/samba/provision/sambadns.py | 12 +++---- python/samba/samdb.py | 4 +-- python/samba/schema.py | 4 +-- 11 files changed, 62 insertions(+), 55 deletions(-) diff --git a/python/samba/__init__.py b/python/samba/__init__.py index f62f5e39202..c5ff45f646a 100644 --- a/python/samba/__init__.py +++ b/python/samba/__init__.py @@ -29,6 +29,7 @@ import samba.param from samba import _glue from samba._ldb import Ldb as _Ldb +from six import string_types def source_tree_topdir(): @@ -247,10 +248,9 @@ def substitute_var(text, values): :param text: Text in which to subsitute. :param values: Dictionary with keys and values. """ - for (name, value) in values.items(): - assert isinstance(name, str), "%r is not a string" % name - assert isinstance(value, str), "Value %r for %s is not a string" % (value, name) + assert isinstance(name, string_types), "%r is not a string" % name + assert isinstance(value, string_types), "Value %r for %s is not a string" % (value, name) text = text.replace("${%s}" % name, value) return text diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py index fb968a56481..e5906523e93 100644 --- a/python/samba/dbchecker.py +++ b/python/samba/dbchecker.py @@ -144,6 +144,7 @@ def __init__(self, samdb, samdb_schema=None, verbose=False, fix=False, for nc in self.ncs: try: + nc = nc.decode('utf8') dn = self.samdb.get_wellknown_dn(ldb.Dn(self.samdb, nc), dsdb.DS_GUID_DELETED_OBJECTS_CONTAINER) self.deleted_objects_containers.append(dn) @@ -178,13 +179,13 @@ def __init__(self, samdb, samdb_schema=None, verbose=False, fix=False, res = self.samdb.search(base=ldb.Dn(self.samdb, self.samdb.get_serverName()), scope=ldb.SCOPE_BASE, attrs=["serverReference"]) # 2. Get server reference - self.server_ref_dn = ldb.Dn(self.samdb, res[0]['serverReference'][0]) + self.server_ref_dn = ldb.Dn(self.samdb, res[0]['serverReference'][0].decode('utf8')) # 3. Get RID Set res = self.samdb.search(base=self.server_ref_dn, scope=ldb.SCOPE_BASE, attrs=['rIDSetReferences']) if "rIDSetReferences" in res[0]: - self.rid_set_dn = ldb.Dn(self.samdb, res[0]['rIDSetReferences'][0]) + self.rid_set_dn = ldb.Dn(self.samdb, res[0]['rIDSetReferences'][0].decode('utf8')) else: self.rid_set_dn = None @@ -1178,7 +1179,7 @@ def check_dn(self, obj, attrname, syntax_oid): obj[attrname] = ldb.MessageElement(vals, 0, attrname) for val in obj[attrname]: - dsdb_dn = dsdb_Dn(self.samdb, val, syntax_oid) + dsdb_dn = dsdb_Dn(self.samdb, val.decode('utf8'), syntax_oid) # all DNs should have a GUID component guid = dsdb_dn.dn.get_extended_component("GUID") diff --git a/python/samba/descriptor.py b/python/samba/descriptor.py index a9c5e1580f0..e4650b294c4 100644 --- a/python/samba/descriptor.py +++ b/python/samba/descriptor.py @@ -413,7 +413,7 @@ def get_wellknown_sds(samdb): attrs=["namingContexts"]) for nc in current[0]["namingContexts"]: - + nc = nc.decode('utf8') dnsforestdn = ldb.Dn(samdb, "DC=ForestDnsZones,%s" % (str(samdb.get_root_basedn()))) if ldb.Dn(samdb, nc) == dnsforestdn: c = (ldb.Dn(samdb, "%s" % str(dnsforestdn)), get_dns_partition_descriptor) diff --git a/python/samba/idmap.py b/python/samba/idmap.py index 0cb729fbc29..a618347fa21 100644 --- a/python/samba/idmap.py +++ b/python/samba/idmap.py @@ -95,4 +95,4 @@ def setup_name_mapping(self, sid, type, unixid=None): cn: %s """ % (sid, unixid, sid, type_string, sid) - self.add(self.parse_ldif(mod).next()[1]) + self.add(next(self.parse_ldif(mod))[1]) 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 889b7f5ef22..97c771f3fc8 100644 --- a/python/samba/ms_schema.py +++ b/python/samba/ms_schema.py @@ -21,6 +21,7 @@ import re import base64 import uuid +from six import string_types bitFields = {} @@ -172,7 +173,7 @@ def fix_dn(dn): def __convert_bitfield(key, value): """Evaluate the OR expression in 'value'""" - assert(isinstance(value, str)) + assert(isinstance(value, string_types)) value = value.replace("\n ", "") value = value.replace(" ", "") @@ -194,7 +195,7 @@ def __write_ldif_one(entry): out = [] for l in entry: - if isinstance(l[1], str): + if isinstance(l[1], string_types): vl = [l[1]] else: vl = l[1] @@ -246,8 +247,7 @@ def __transform_entry(entry, objectClass): if not l[2]: l[1] = oMObjectClassBER[l[1].strip()] l[2] = True - - if isinstance(l[1], str): + if isinstance(l[1], string_types): l[1] = fix_dn(l[1]) if key == 'dn': @@ -286,8 +286,9 @@ def __parse_schema_file(filename, objectClass): """Load and transform a schema file.""" out = [] + from io import open + f = open(filename, "r", encoding='latin-1') - f = open(filename, "rU") for entry in __read_raw_entries(f): out.append(__write_ldif_one(__transform_entry(entry, objectClass))) diff --git a/python/samba/netcmd/fsmo.py b/python/samba/netcmd/fsmo.py index 41e45592b46..14b8fa6c791 100644 --- a/python/samba/netcmd/fsmo.py +++ b/python/samba/netcmd/fsmo.py @@ -47,7 +47,7 @@ def get_fsmo_roleowner(samdb, roledn, role): raise if 'fSMORoleOwner' in res[0]: - master_owner = (ldb.Dn(samdb, res[0]["fSMORoleOwner"][0])) + master_owner = (ldb.Dn(samdb, res[0]["fSMORoleOwner"][0].decode('utf8'))) else: master_owner = None diff --git a/python/samba/provision/__init__.py b/python/samba/provision/__init__.py index dcdb2b7bd20..852452f0277 100644 --- a/python/samba/provision/__init__.py +++ b/python/samba/provision/__init__.py @@ -25,7 +25,9 @@ """Functions for setting up a Samba configuration.""" __docformat__ = "restructuredText" - +from future.utils import iteritems +from six.moves.urllib.parse import quote +from six import string_types from base64 import b64encode import errno import os @@ -774,11 +776,11 @@ def make_smbconf(smbconf, hostname, domain, realm, targetdir, f = open(smbconf, 'w') try: f.write("[globals]\n") - for key, val in global_settings.iteritems(): + for key, val in iteritems(global_settings): f.write("\t%s = %s\n" % (key, val)) f.write("\n") - for name, path in shares.iteritems(): + for name, path in iteritems(shares): f.write("[%s]\n" % name) f.write("\tpath = %s\n" % path) f.write("\tread only = no\n") @@ -1070,7 +1072,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) @@ -1144,7 +1146,7 @@ def setup_self_join(samdb, admin_session_info, names, fill, machinepass, "INVOCATIONID": invocationid, "NETBIOSNAME": names.netbiosname, "DNSNAME": "%s.%s" % (names.hostname, names.dnsdomain), - "MACHINEPASS_B64": b64encode(machinepass.encode('utf-16-le')), + "MACHINEPASS_B64": b64encode(machinepass.encode('utf-16-le')).decode('utf8'), "DOMAINSID": str(domainsid), "DCRID": str(dc_rid), "SAMBA_VERSION_STRING": version, @@ -1171,7 +1173,7 @@ def setup_self_join(samdb, admin_session_info, names, fill, machinepass, "INVOCATIONID": invocationid, "NETBIOSNAME": names.netbiosname, "DNSNAME": "%s.%s" % (names.hostname, names.dnsdomain), - "MACHINEPASS_B64": b64encode(machinepass.encode('utf-16-le')), + "MACHINEPASS_B64": b64encode(machinepass.encode('utf-16-le')).decode('utf8'), "DOMAINSID": str(domainsid), "DCRID": str(dc_rid), "SAMBA_VERSION_STRING": version, @@ -1367,7 +1369,7 @@ def fill_samdb(samdb, lp, names, logger, policyguid, else: domainguid_line = "" - descr = b64encode(get_domain_descriptor(names.domainsid)) + descr = b64encode(get_domain_descriptor(names.domainsid)).decode('utf8') setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), { "DOMAINDN": names.domaindn, "DOMAINSID": str(names.domainsid), @@ -1390,7 +1392,7 @@ def fill_samdb(samdb, lp, names, logger, policyguid, # If we are setting up a subdomain, then this has been replicated in, so we don't need to add it if fill == FILL_FULL: logger.info("Adding configuration container") - descr = b64encode(get_config_descriptor(names.domainsid)) + descr = b64encode(get_config_descriptor(names.domainsid)).decode('utf8') setup_add_ldif(samdb, setup_path("provision_configuration_basedn.ldif"), { "CONFIGDN": names.configdn, "DESCRIPTOR": descr, @@ -1420,12 +1422,12 @@ def fill_samdb(samdb, lp, names, logger, policyguid, if fill == FILL_FULL: logger.info("Setting up sam.ldb configuration data") - partitions_descr = b64encode(get_config_partitions_descriptor(names.domainsid)) - sites_descr = b64encode(get_config_sites_descriptor(names.domainsid)) - ntdsquotas_descr = b64encode(get_config_ntds_quotas_descriptor(names.domainsid)) - protected1_descr = b64encode(get_config_delete_protected1_descriptor(names.domainsid)) - protected1wd_descr = b64encode(get_config_delete_protected1wd_descriptor(names.domainsid)) - protected2_descr = b64encode(get_config_delete_protected2_descriptor(names.domainsid)) + partitions_descr = b64encode(get_config_partitions_descriptor(names.domainsid)).decode('utf8') + sites_descr = b64encode(get_config_sites_descriptor(names.domainsid)).decode('utf8') + ntdsquotas_descr = b64encode(get_config_ntds_quotas_descriptor(names.domainsid)).decode('utf8') + protected1_descr = b64encode(get_config_delete_protected1_descriptor(names.domainsid)).decode('utf8') + protected1wd_descr = b64encode(get_config_delete_protected1wd_descriptor(names.domainsid)).decode('utf8') + protected2_descr = b64encode(get_config_delete_protected2_descriptor(names.domainsid)).decode('utf8') if "2008" in schema.base_schema: # exclude 2012-specific changes if we're using a 2008 schema @@ -1475,7 +1477,7 @@ def fill_samdb(samdb, lp, names, logger, policyguid, }) logger.info("Adding users container") - users_desc = b64encode(get_domain_users_descriptor(names.domainsid)) + users_desc = b64encode(get_domain_users_descriptor(names.domainsid)).decode('utf8') setup_add_ldif(samdb, setup_path("provision_users_add.ldif"), { "DOMAINDN": names.domaindn, "USERS_DESCRIPTOR": users_desc @@ -1484,7 +1486,7 @@ def fill_samdb(samdb, lp, names, logger, policyguid, setup_modify_ldif(samdb, setup_path("provision_users_modify.ldif"), { "DOMAINDN": names.domaindn}) logger.info("Adding computers container") - computers_desc = b64encode(get_domain_computers_descriptor(names.domainsid)) + computers_desc = b64encode(get_domain_computers_descriptor(names.domainsid)).decode('utf8') setup_add_ldif(samdb, setup_path("provision_computers_add.ldif"), { "DOMAINDN": names.domaindn, "COMPUTERS_DESCRIPTOR": computers_desc @@ -1494,11 +1496,11 @@ def fill_samdb(samdb, lp, names, logger, policyguid, setup_path("provision_computers_modify.ldif"), { "DOMAINDN": names.domaindn}) logger.info("Setting up sam.ldb data") - infrastructure_desc = b64encode(get_domain_infrastructure_descriptor(names.domainsid)) - lostandfound_desc = b64encode(get_domain_delete_protected2_descriptor(names.domainsid)) - system_desc = b64encode(get_domain_delete_protected1_descriptor(names.domainsid)) - builtin_desc = b64encode(get_domain_builtin_descriptor(names.domainsid)) - controllers_desc = b64encode(get_domain_controllers_descriptor(names.domainsid)) + infrastructure_desc = b64encode(get_domain_infrastructure_descriptor(names.domainsid)).decode('utf8') + lostandfound_desc = b64encode(get_domain_delete_protected2_descriptor(names.domainsid)).decode('utf8') + system_desc = b64encode(get_domain_delete_protected1_descriptor(names.domainsid)).decode('utf8') + builtin_desc = b64encode(get_domain_builtin_descriptor(names.domainsid)).decode('utf8') + controllers_desc = b64encode(get_domain_controllers_descriptor(names.domainsid)).decode('utf8') setup_add_ldif(samdb, setup_path("provision.ldif"), { "CREATTIME": str(samba.unix2nttime(int(time.time()))), "DOMAINDN": names.domaindn, @@ -1517,14 +1519,14 @@ def fill_samdb(samdb, lp, names, logger, policyguid, # If we are setting up a subdomain, then this has been replicated in, so we don't need to add it if fill == FILL_FULL: - managedservice_descr = b64encode(get_managed_service_accounts_descriptor(names.domainsid)) + managedservice_descr = b64encode(get_managed_service_accounts_descriptor(names.domainsid)).decode('utf8') setup_modify_ldif(samdb, setup_path("provision_configuration_references.ldif"), { "CONFIGDN": names.configdn, "SCHEMADN": names.schemadn}) logger.info("Setting up well known security principals") - protected1wd_descr = b64encode(get_config_delete_protected1wd_descriptor(names.domainsid)) + protected1wd_descr = b64encode(get_config_delete_protected1wd_descriptor(names.domainsid)).decode('utf8') setup_add_ldif(samdb, setup_path("provision_well_known_sec_princ.ldif"), { "CONFIGDN": names.configdn, "WELLKNOWNPRINCIPALS_DESCRIPTOR": protected1wd_descr, @@ -1541,8 +1543,8 @@ def fill_samdb(samdb, lp, names, logger, policyguid, setup_add_ldif(samdb, setup_path("provision_users.ldif"), { "DOMAINDN": names.domaindn, "DOMAINSID": str(names.domainsid), - "ADMINPASS_B64": b64encode(adminpass.encode('utf-16-le')), - "KRBTGTPASS_B64": b64encode(krbtgtpass.encode('utf-16-le')) + "ADMINPASS_B64": b64encode(adminpass.encode('utf-16-le')).decode('utf8'), + "KRBTGTPASS_B64": b64encode(krbtgtpass.encode('utf-16-le')).decode('utf8') }, controls=["relax:0", "provision:0"]) logger.info("Setting up self join") @@ -1562,7 +1564,9 @@ 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) + # should we leave it as bytes ? or convert it to string ? or... + names.ntdsguid = names.ntdsguid.decode('ascii') + assert isinstance(names.ntdsguid, string_types) return samdb @@ -1920,7 +1924,7 @@ def provision_fill(samdb, secrets_ldb, logger, names, paths, msg = ldb.Message(ldb.Dn(samdb, samdb.searchone("distinguishedName", expression="samAccountName=%s$" % names.netbiosname, - scope=ldb.SCOPE_SUBTREE))) + scope=ldb.SCOPE_SUBTREE).decode('utf8'))) msg["msDS-SupportedEncryptionTypes"] = ldb.MessageElement( elements=kerberos_enctypes, flags=ldb.FLAG_MOD_REPLACE, name="msDS-SupportedEncryptionTypes") @@ -1938,8 +1942,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('ascii') + assert isinstance(domainguid, string_types) lastProvisionUSNs = get_last_provision_usn(samdb) maxUSN = get_max_usn(samdb, str(names.rootdn)) @@ -2189,7 +2193,7 @@ def provision(logger, session_info, smbconf=None, if paths.sysvol and not os.path.exists(paths.sysvol): os.makedirs(paths.sysvol, 0o775) - ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="") + ldapi_url = "ldapi://%s" % quote(paths.s4_ldapi_path, safe="") schema = Schema(domainsid, invocationid=invocationid, schemadn=names.schemadn, base_schema=base_schema) diff --git a/python/samba/provision/sambadns.py b/python/samba/provision/sambadns.py index 7a85546c53e..eb87981b21b 100644 --- a/python/samba/provision/sambadns.py +++ b/python/samba/provision/sambadns.py @@ -247,12 +247,12 @@ def setup_dns_partitions(samdb, domainsid, domaindn, forestdn, configdn, setup_add_ldif(samdb, setup_path("provision_dnszones_partitions.ldif"), { "ZONE_DN": domainzone_dn, - "SECDESC" : b64encode(descriptor) + "SECDESC" : b64encode(descriptor).decode('ascii') }) if fill_level != FILL_SUBDOMAIN: setup_add_ldif(samdb, setup_path("provision_dnszones_partitions.ldif"), { "ZONE_DN": forestzone_dn, - "SECDESC" : b64encode(descriptor) + "SECDESC" : b64encode(descriptor).decode('ascii') }) domainzone_guid = get_domainguid(samdb, domainzone_dn) @@ -267,8 +267,8 @@ def setup_dns_partitions(samdb, domainsid, domaindn, forestdn, configdn, "ZONE_DNS": domainzone_dns, "CONFIGDN": configdn, "SERVERDN": serverdn, - "LOSTANDFOUND_DESCRIPTOR": b64encode(protected2_desc), - "INFRASTRUCTURE_DESCRIPTOR": b64encode(protected1_desc), + "LOSTANDFOUND_DESCRIPTOR": b64encode(protected2_desc).decode('ascii'), + "INFRASTRUCTURE_DESCRIPTOR": b64encode(protected1_desc).decode('ascii'), }) setup_modify_ldif(samdb, setup_path("provision_dnszones_modify.ldif"), { "CONFIGDN": configdn, @@ -287,8 +287,8 @@ def setup_dns_partitions(samdb, domainsid, domaindn, forestdn, configdn, "ZONE_DNS": forestzone_dns, "CONFIGDN": configdn, "SERVERDN": serverdn, - "LOSTANDFOUND_DESCRIPTOR": b64encode(protected2_desc), - "INFRASTRUCTURE_DESCRIPTOR": b64encode(protected1_desc), + "LOSTANDFOUND_DESCRIPTOR": b64encode(protected2_desc).decode('ascii'), + "INFRASTRUCTURE_DESCRIPTOR": b64encode(protected1_desc).decode('ascii'), }) setup_modify_ldif(samdb, setup_path("provision_dnszones_modify.ldif"), { "CONFIGDN": configdn, diff --git a/python/samba/samdb.py b/python/samba/samdb.py index b66afb7431c..a1a1f45b003 100644 --- a/python/samba/samdb.py +++ b/python/samba/samdb.py @@ -1024,12 +1024,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 67ec357a285..e3dda066b50 100644 --- a/python/samba/schema.py +++ b/python/samba/schema.py @@ -122,7 +122,7 @@ def __init__(self, domain_sid, invocationid=None, schemadn=None, setup_path("provision_schema_basedn_modify.ldif"), {"SCHEMADN": schemadn, "OBJVERSION" : schema_version}) - descr = b64encode(get_schema_descriptor(domain_sid)) + descr = b64encode(get_schema_descriptor(domain_sid)).decode('utf8') self.schema_dn_add = read_and_sub_file( setup_path("provision_schema_basedn.ldif"), {"SCHEMADN": schemadn, "DESCRIPTOR": descr}) @@ -136,7 +136,7 @@ def __init__(self, domain_sid, invocationid=None, schemadn=None, for map in additional_prefixmap: self.prefixmap_data += "%s\n" % map - self.prefixmap_data = b64encode(self.prefixmap_data) + self.prefixmap_data = b64encode(self.prefixmap_data.encode('utf8')).decode('utf8') # We don't actually add this ldif, just parse it prefixmap_ldif = "dn: %s\nprefixMap:: %s\n\n" % (self.schemadn, self.prefixmap_data) From ca0f72a11da83ecaa088e680de11ac663f820dcf Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 10 Apr 2018 16:03:37 +0100 Subject: [PATCH 2/2] 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 1ab1fff7c16..b955569184d 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -578,7 +578,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") 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") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.unix") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.srvsvc")