From 983b587fd36e453d89cd79afd4550a137036def9 Mon Sep 17 00:00:00 2001 From: Douglas Bagnall Date: Sun, 28 Oct 2018 11:12:48 +1300 Subject: [PATCH 1/7] s4/scripting/*: py3 compatible print Signed-off-by: Douglas Bagnall Reviewed-by: Noel Power (cherry picked from commit 78f5b6e3999a0bf4a118df36a2aabcb696049792) --- source4/scripting/bin/enablerecyclebin | 2 +- source4/scripting/bin/findprovisionusnranges | 14 ++++++-------- source4/scripting/bin/fullschema | 2 +- source4/scripting/bin/get-descriptors | 2 +- source4/scripting/bin/minschema | 2 +- source4/scripting/bin/mymachinepw | 7 +++---- source4/scripting/bin/rebuildextendeddn | 12 +++++++----- source4/scripting/bin/sambaundoguididx | 2 +- source4/scripting/bin/smbstatus | 10 ++++++---- source4/scripting/devel/addlotscontacts | 2 +- source4/scripting/devel/config_base | 2 +- source4/scripting/devel/crackname | 2 +- source4/scripting/devel/enumprivs | 2 +- source4/scripting/devel/getncchanges | 2 +- 14 files changed, 32 insertions(+), 31 deletions(-) diff --git a/source4/scripting/bin/enablerecyclebin b/source4/scripting/bin/enablerecyclebin index ab36ead1b8f..a179698b7fe 100755 --- a/source4/scripting/bin/enablerecyclebin +++ b/source4/scripting/bin/enablerecyclebin @@ -50,4 +50,4 @@ msg["enableOptionalFeature"] = ldb.MessageElement( ldb.FLAG_MOD_ADD, "enableOptionalFeature") res = sam_ldb.modify(msg) -print "Recycle Bin feature enabled" +print("Recycle Bin feature enabled") diff --git a/source4/scripting/bin/findprovisionusnranges b/source4/scripting/bin/findprovisionusnranges index ee9da3d421e..540869dbae4 100755 --- a/source4/scripting/bin/findprovisionusnranges +++ b/source4/scripting/bin/findprovisionusnranges @@ -18,7 +18,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - import sys import optparse sys.path.insert(0, "bin/python") @@ -63,18 +62,17 @@ if res and len(res) == 1 and res[0]["dsServiceName"] != None: if res and len(res) == 1 and res[0]["invocationId"]: invocation = str(ndr_unpack(misc.GUID, res[0]["invocationId"][0])) else: - print "Unable to find invocation ID" + print("Unable to find invocation ID") sys.exit(1) else: - print "Unable to find attribute dsServiceName in rootDSE" + print("Unable to find attribute dsServiceName in rootDSE") sys.exit(1) minobj = 5 (hash_id, nb_obj) = findprovisionrange(samdb, basedn) -print "Here is a list of changes that modified more than %d objects in 1 minute." % minobj -print "Usually changes made by provision and upgradeprovision are those who affect a couple"\ - " of hundred of objects or more" -print "Total number of objects: %d" % nb_obj -print +print("Here is a list of changes that modified more than %d objects in 1 minute." % minobj) +print("Usually changes made by provision and upgradeprovision are those who affect a couple" + " of hundred of objects or more") +print("Total number of objects: %d\n" % nb_obj) print_provision_ranges(hash_id, minobj, opts.storedir, str(paths.samdb), invocation) diff --git a/source4/scripting/bin/fullschema b/source4/scripting/bin/fullschema index ab0e4e320bd..596de01b91c 100755 --- a/source4/scripting/bin/fullschema +++ b/source4/scripting/bin/fullschema @@ -132,7 +132,7 @@ def fix_dn(dn): def write_ldif_one(o, attrs): """dump an object as ldif""" - print "dn: CN=%s,${SCHEMADN}" % o["cn"] + print("dn: CN=%s,${SCHEMADN}" % o["cn"]) for a in attrs: if not o.has_key(a): continue diff --git a/source4/scripting/bin/get-descriptors b/source4/scripting/bin/get-descriptors index f1a919c3748..70926cdccbb 100755 --- a/source4/scripting/bin/get-descriptors +++ b/source4/scripting/bin/get-descriptors @@ -90,7 +90,7 @@ class DescrGetter: for line in ldif_entry: length = 79 if len(line) <= length + 1: - print line + print(line) else: for i in range(len(line) / length + 1): if i == 0: diff --git a/source4/scripting/bin/minschema b/source4/scripting/bin/minschema index 176ad5c93b9..eba198696e2 100755 --- a/source4/scripting/bin/minschema +++ b/source4/scripting/bin/minschema @@ -191,7 +191,7 @@ def fix_dn(dn): def write_ldif_one(o, attrs): """dump an object as ldif""" - print "dn: CN=%s,${SCHEMADN}" % o["cn"] + print("dn: CN=%s,${SCHEMADN}" % o["cn"]) for a in attrs: if not o.has_key(a): continue diff --git a/source4/scripting/bin/mymachinepw b/source4/scripting/bin/mymachinepw index dc85ad1df44..91dc502a634 100755 --- a/source4/scripting/bin/mymachinepw +++ b/source4/scripting/bin/mymachinepw @@ -19,7 +19,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - import samba.param as param, ldb, sys, getopt optlist, args = getopt.getopt(sys.argv[1:], "s:") @@ -48,9 +47,9 @@ search = ("(&(objectclass=primaryDomain)(samaccountname=" + msg = secrets.search(expression=search, attrs=['secret']) if not msg: - print "Error:" - print "Password for host[%s] not found in path[%s]." % (netbios, path) - print "You may want to pass the smb.conf location via the -s option." + print("Error:") + print("Password for host[%s] not found in path[%s]." % (netbios, path)) + print("You may want to pass the smb.conf location via the -s option.") exit(1) password=msg[0]['secret'][0] diff --git a/source4/scripting/bin/rebuildextendeddn b/source4/scripting/bin/rebuildextendeddn index 5a0ab1295a6..5f5e05da795 100755 --- a/source4/scripting/bin/rebuildextendeddn +++ b/source4/scripting/bin/rebuildextendeddn @@ -21,7 +21,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - +from __future__ import print_function import optparse import os import sys @@ -53,7 +53,7 @@ opts = parser.parse_args()[0] def message(text): """print a message if quiet is not set.""" if not opts.quiet: - print text + print(text) if len(sys.argv) == 1: opts.interactive = True @@ -77,7 +77,7 @@ def get_paths(targetdir=None,smbconf=None): smbconf = param.default_path() if not os.path.exists(smbconf): - print >>sys.stderr, "Unable to find smb.conf .. "+smbconf + print("Unable to find smb.conf .. "+smbconf, file=sys.stderr) parser.print_usage() sys.exit(1) @@ -121,9 +121,11 @@ def rebuild_en_dn(credentials,session_info,paths): sam_ldb.modify(m) res3 = sam_ldb.search(expression="(&(distinguishedName=%s)(%s=*))"%(dn,att),scope=SCOPE_SUBTREE, attrs=[att],controls=["search_options:1:2"]) if( len(res3) == 0 or (len(res3[0][att])!= len(saveatt))): - print >>sys.stderr, str(dn) + " has no attr " +att+ " or a wrong value" + print(str(dn) + " has no attr " +att+ " or a wrong value", + file=sys.stderr) for satt in saveatt: - print >>sys.stderr,str(att)+" = "+satt + print("%s = %s" % (att, satt), + file=sys.stderr) sam_ldb.transaction_cancel() sam_ldb.transaction_commit() diff --git a/source4/scripting/bin/sambaundoguididx b/source4/scripting/bin/sambaundoguididx index 41d2030e075..ef0f525818d 100755 --- a/source4/scripting/bin/sambaundoguididx +++ b/source4/scripting/bin/sambaundoguididx @@ -70,7 +70,7 @@ for db in dbs: samdb.transaction_commit() -print "Re-opening with the full DB stack" +print("Re-opening with the full DB stack") samdb = SamDB(url=url, lp=lp_ctx) print "Re-triggering another re-index" diff --git a/source4/scripting/bin/smbstatus b/source4/scripting/bin/smbstatus index 473dbaf2ce4..c2834ab12ab 100755 --- a/source4/scripting/bin/smbstatus +++ b/source4/scripting/bin/smbstatus @@ -27,12 +27,14 @@ def show_sessions(conn): """show open sessions""" sessions = next(conn.smbsrv_information(irpc.SMBSRV_INFO_SESSIONS)) - print "User Client Connected at" - print "-" * 79 + print("User Client Connected at") + print("-" * 79) for session in sessions: fulluser = "%s/%s" % (session.account_name, session.domain_name) - print "%-30s %16s %s" % (fulluser, session.client_ip, sys.httptime(session.connect_time)) - print "" + print("%-30s %16s %s" % (fulluser, + session.client_ip, + sys.httptime(session.connect_time))) + print() def show_tcons(open_connection): """show open tree connects""" diff --git a/source4/scripting/devel/addlotscontacts b/source4/scripting/devel/addlotscontacts index edf54b0bade..e8b2c1af1aa 100644 --- a/source4/scripting/devel/addlotscontacts +++ b/source4/scripting/devel/addlotscontacts @@ -75,7 +75,7 @@ if __name__ == '__main__': ldbs.sam.add(msg) - print "Creating %d contacts" % num_contacts + print("Creating %d contacts" % num_contacts) count = 0 increment = num_contacts / 10 if increment > 5000: diff --git a/source4/scripting/devel/config_base b/source4/scripting/devel/config_base index e48d3a6ce14..9c4f07209dd 100755 --- a/source4/scripting/devel/config_base +++ b/source4/scripting/devel/config_base @@ -37,4 +37,4 @@ for v in vars: options = options.replace("${PREFIX}", prefix) -print options +print(options) diff --git a/source4/scripting/devel/crackname b/source4/scripting/devel/crackname index 2e1798511f3..0ae177c133f 100755 --- a/source4/scripting/devel/crackname +++ b/source4/scripting/devel/crackname @@ -56,7 +56,7 @@ if __name__ == "__main__": drs = drsuapi.drsuapi(binding_str, lp, creds) drs_handle = do_DsBind(drs) - print "DRS Handle: %s" % drs_handle + print("DRS Handle: %s" % drs_handle) req = drsuapi.DsNameRequest1() names = drsuapi.DsNameString() diff --git a/source4/scripting/devel/enumprivs b/source4/scripting/devel/enumprivs index 6a040402ae3..33597f9388a 100755 --- a/source4/scripting/devel/enumprivs +++ b/source4/scripting/devel/enumprivs @@ -55,4 +55,4 @@ if __name__ == "__main__": (handle, privs) = lsaconn.EnumPrivs(pol_handle, 0, 100) for p in privs.privs: disp_name = get_display_name(lsaconn, pol_handle, p.name.string) - print "0x%08x %31s \"%s\"" % (p.luid.low, p.name.string, disp_name) + print("0x%08x %31s \"%s\"" % (p.luid.low, p.name.string, disp_name)) diff --git a/source4/scripting/devel/getncchanges b/source4/scripting/devel/getncchanges index 9b6361b3548..9c25e39f756 100755 --- a/source4/scripting/devel/getncchanges +++ b/source4/scripting/devel/getncchanges @@ -76,7 +76,7 @@ if __name__ == "__main__": drs = drsuapi.drsuapi(binding_str, lp, creds) drs_handle, supported_extensions = drs_DsBind(drs) - print "DRS Handle: %s" % drs_handle + print("DRS Handle: %s" % drs_handle) req8 = drsuapi.DsGetNCChangesRequest8() -- 2.17.1 From b277f1537e7f0c1612b2d28445ece1ea1c544ae4 Mon Sep 17 00:00:00 2001 From: Douglas Bagnall Date: Sat, 9 Mar 2019 13:48:29 +1300 Subject: [PATCH 2/7] s4/scripting: MORE py3 compatible print functions BUG: https://bugzilla.samba.org/show_bug.cgi?id=13978 Signed-off-by: Douglas Bagnall Reviewed-by: Andrew Bartlett (cherry picked from commit 561b654bc5bc2f5e614c5c2ab378193ca94d481a) --- source4/scripting/bin/autoidl | 19 +++++----- source4/scripting/bin/fullschema | 9 ++--- source4/scripting/bin/get-descriptors | 9 ++--- source4/scripting/bin/minschema | 47 +++++++++++++------------ source4/scripting/bin/sambaundoguididx | 8 +++-- source4/scripting/bin/smbstatus | 19 +++++----- source4/scripting/devel/addlotscontacts | 4 +-- source4/scripting/devel/crackname | 10 +++--- source4/scripting/devel/getncchanges | 8 ++--- 9 files changed, 71 insertions(+), 62 deletions(-) diff --git a/source4/scripting/bin/autoidl b/source4/scripting/bin/autoidl index 6a13caa2510..cbd696e56ef 100755 --- a/source4/scripting/bin/autoidl +++ b/source4/scripting/bin/autoidl @@ -17,6 +17,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # +from __future__ import print_function import sys @@ -107,25 +108,25 @@ class Function: if base_request is None: raise Exception("Unable to determine base size for opnum %d" % self.opnum) - print "\tBase request is %r" % base_request + print("\tBase request is %r" % base_request) decision_byte_map = map(lambda x: self.check_decision_byte(base_request, x), range(len(base_request))) - print decision_byte_map + print(decision_byte_map) # find pointers possible_pointers = map(all, [decision_byte_map[i*4:(i+1)*4] for i in range(int(len(base_request)/4))]) - print possible_pointers + print(possible_pointers) pointer_deferrant_bases = map( lambda x: self.find_deferrant_data(base_request, x) if possible_pointers[x] else None, range(len(possible_pointers))) - print pointer_deferrant_bases + print(pointer_deferrant_bases) if len(sys.argv) < 3: - print "Usage: autoidl []" + print("Usage: autoidl []") sys.exit(1) (binding, uuid) = sys.argv[1:3] @@ -147,15 +148,15 @@ if version is None: else: conn = ClientConnection(binding, (uuid, version)) -print "Figuring out number of connections...", +print("Figuring out number of connections... ", end='') num_funcs = find_num_funcs(conn) -print "%d" % num_funcs +print("%d" % num_funcs) # Figure out the syntax for each one for i in range(num_funcs): - print "Function %d" % i + print("Function %d" % i) data = Function(conn, i) try: data.find_idl() except Exception as e: - print "Error: %r" % e + print("Error: %r" % e) diff --git a/source4/scripting/bin/fullschema b/source4/scripting/bin/fullschema index 596de01b91c..092cd484400 100755 --- a/source4/scripting/bin/fullschema +++ b/source4/scripting/bin/fullschema @@ -2,6 +2,7 @@ # # Works out the full schema # +from __future__ import print_function import base64 import optparse @@ -147,12 +148,12 @@ def write_ldif_one(o, attrs): value = fix_dn(j) if a != "cn": if a == "oMObjectClass": - print "%s:: %s" % (a, base64.b64encode(value)).decode('utf8') + print("%s:: %s" % (a, base64.b64encode(value)).decode('utf8')) elif a.endswith("GUID"): - print "%s: %s" % (a, ldb.schema_format_value(a, value)) + print("%s: %s" % (a, ldb.schema_format_value(a, value))) else: - print "%s: %s" % (a, value) - print "" + print("%s: %s" % (a, value)) + print() # get the rootDSE diff --git a/source4/scripting/bin/get-descriptors b/source4/scripting/bin/get-descriptors index 70926cdccbb..bedd31fad8c 100755 --- a/source4/scripting/bin/get-descriptors +++ b/source4/scripting/bin/get-descriptors @@ -26,6 +26,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # +from __future__ import print_function import optparse import sys @@ -97,12 +98,12 @@ class DescrGetter: l = line[i * length:((i + 1) * length)] else: l = " " + line[(i * length):((i + 1) * length)] - print l - print "\n" + print(l) + print("\n") def write_as_sddl(self, dn, descr): - print dn - print descr + "\n" + print(dn) + print(descr + "\n") def read_descr_by_base(self, search_base): res = self.samdb.search(base=search_base + self.local_domain, expression="(objectClass=*)", scope=SCOPE_SUBTREE, attrs=["nTSecurityDescriptor"]) diff --git a/source4/scripting/bin/minschema b/source4/scripting/bin/minschema index eba198696e2..8907e6899b6 100755 --- a/source4/scripting/bin/minschema +++ b/source4/scripting/bin/minschema @@ -2,7 +2,7 @@ # # Works out the minimal schema for a set of objectclasses # - +from __future__ import print_function import base64 import optparse import sys @@ -251,15 +251,15 @@ def find_objectclass_auto(ldb, o): return testdn = create_testdn(o.exampleDN) - print "testdn is '%s'" % testdn + print("testdn is '%s'" % testdn) ldif = "dn: " + testdn ldif += "\nobjectClass: " + o.name try: ldb.add(ldif) except LdbError as e: - print "error adding %s: %s" % (o.name, e) - print "%s" % ldif + print("error adding %s: %s" % (o.name, e)) + print("%s" % ldif) return res = ldb.search(base=testdn, scope=ldb.SCOPE_BASE) @@ -279,7 +279,7 @@ def expand_objectclass(ldb, o): expression="(&(objectClass=classSchema)(ldapDisplayName=%s))" % o.name, base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE, attrs=attrs) - print >>sys.stderr, "Expanding class %s" % o.name + print("Expanding class %s" % o.name, file=sys.stderr) assert(len(res) == 1) msg = res[0] for aname in attrs: @@ -290,7 +290,7 @@ def expand_objectclass(ldb, o): list = [msg[aname]] for name in list: if not objectclasses.has_key(name): - print >>sys.stderr, "Found new objectclass '%s'" % name + print("Found new objectclass '%s'" % name, file=sys.stderr) objectclasses[name] = Objectclass(ldb, name) @@ -317,13 +317,15 @@ def walk_dn(ldb, dn): try: res = ldb.search("objectClass=*", dn, SCOPE_BASE, attrs) except LdbError as e: - print >>sys.stderr, "Unable to fetch allowedAttributes for '%s' - %r" % (dn, e) + print("Unable to fetch allowedAttributes for '%s' - %r" % (dn, e), + file=sys.stderr) return allattrs = res[0]["allowedAttributes"] try: res = ldb.search("objectClass=*", dn, SCOPE_BASE, allattrs) except LdbError as e: - print >>sys.stderr, "Unable to fetch all attributes for '%s' - %s" % (dn, e) + print("Unable to fetch all attributes for '%s' - %s" % (dn, e), + file=sys.stderr) return msg = res[0] for a in msg: @@ -336,7 +338,8 @@ def walk_naming_context(ldb, namingContext): res = ldb.search("objectClass=*", namingContext, SCOPE_DEFAULT, ["objectClass"]) except LdbError as e: - print >>sys.stderr, "Unable to fetch objectClasses for '%s' - %s" % (namingContext, e) + print("Unable to fetch objectClasses for '%s' - %s" % (namingContext, e), + file=sys.stderr) return for msg in res: msg = res.msgs[r]["objectClass"] @@ -389,7 +392,7 @@ def build_objectclass(ldb, name): base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE, attrs=attrs) if len(res) == 0: - print >>sys.stderr, "unknown class '%s'" % name + print("unknown class '%s'" % name, file=sys.stderr) return None return Objectclass(ldb, name) @@ -424,7 +427,7 @@ def write_aggregate_objectclass(objectclass): list = attribute_list(objectclass, "systemMayContain", "mayContain") line += aggregate_list("MAY", list) - print line + " )" + print(line + " )") def write_aggregate_ditcontentrule(objectclass): @@ -451,7 +454,7 @@ def write_aggregate_ditcontentrule(objectclass): line += aggregate_list("MUST", must_list) line += aggregate_list("MAY", may_list) - print line + " )" + print(line + " )") def write_aggregate_attribute(attrib): """write the aggregate record for an attribute""" @@ -463,15 +466,15 @@ def write_aggregate_attribute(attrib): if attrib.get('systemOnly') == "TRUE": line += "NO-USER-MODIFICATION " - print line + ")" + print(line + ")") def write_aggregate(): """write the aggregate record""" - print "dn: CN=Aggregate,${SCHEMADN}" - print """objectClass: top + print("dn: CN=Aggregate,${SCHEMADN}") + print("""objectClass: top objectClass: subSchema -objectCategory: CN=SubSchema,${SCHEMADN}""" +objectCategory: CN=SubSchema,${SCHEMADN}""") if not opts.dump_subschema_auto: return @@ -552,15 +555,15 @@ if not opts.verbose: # # dump list of objectclasses # -print "objectClasses:\n" +print("objectClasses:\n") for objectclass in objectclasses: - print "\t%s\n" % objectclass + print("\t%s\n" % objectclass) -print "attributes:\n" +print("attributes:\n") for attr in attributes: - print "\t%s\n" % attr + print("\t%s\n" % attr) -print "autocreated attributes:\n" +print("autocreated attributes:\n") for attr in attributes: if attr.autocreate: - print "\t%s\n" % i + print("\t%s\n" % i) diff --git a/source4/scripting/bin/sambaundoguididx b/source4/scripting/bin/sambaundoguididx index ef0f525818d..adff232e022 100755 --- a/source4/scripting/bin/sambaundoguididx +++ b/source4/scripting/bin/sambaundoguididx @@ -1,4 +1,5 @@ #!/usr/bin/env python +from __future__ import print_function import optparse import sys @@ -73,11 +74,12 @@ samdb.transaction_commit() print("Re-opening with the full DB stack") samdb = SamDB(url=url, lp=lp_ctx) -print "Re-triggering another re-index" +print("Re-triggering another re-index") chk = dbcheck(samdb) chk.reindex_database() -print "Your database has been downgraded to DN-based index values." +print("Your database has been downgraded to DN-based index values.") -print "NOTE: Any use of a Samba 4.8 tool including ldbsearch will auto-upgrade back to GUID index mode" +print("NOTE: Any use of a Samba 4.8 tool including ldbsearch will " + "auto-upgrade back to GUID index mode") diff --git a/source4/scripting/bin/smbstatus b/source4/scripting/bin/smbstatus index c2834ab12ab..1d1b71627aa 100755 --- a/source4/scripting/bin/smbstatus +++ b/source4/scripting/bin/smbstatus @@ -8,7 +8,7 @@ # Copyright Andrew Tridgell 2005 # Released under the GNU GPL version 3 or later # - +from __future__ import print_function import os, sys # make sure the script dies immediately when hitting control-C, @@ -40,25 +40,26 @@ def show_tcons(open_connection): """show open tree connects""" conn = open_connection("smb_server") tcons = next(conn.smbsrv_information(irpc.SMBSRV_INFO_TCONS)) - print "Share Client Connected at" - print "-" * 79 + print("Share Client Connected at") + print("-" * 79) for tcon in tcons: - print "%-30s %16s %s" % (tcon.share_name, tcon.client_ip, sys.httptime(tcon.connect_time)) + print("%-30s %16s %s" % + (tcon.share_name, tcon.client_ip, sys.httptime(tcon.connect_time))) def show_nbt(open_connection): """show nbtd information""" conn = open_connection("nbt_server") stats = next(conn.nbtd_information(irpc.NBTD_INFO_STATISTICS)) - print "NBT server statistics:" + print("NBT server statistics:") fields = [("total_received", "Total received"), ("total_sent", "Total sent"), ("query_count", "Query count"), ("register_count", "Register count"), ("release_count", "Release count")] for (field, description) in fields: - print "\t%s:\t%s" % (description, getattr(stats, field)) - print + print("\t%s:\t%s" % (description, getattr(stats, field))) + print() parser = optparse.OptionParser("%s [options]" % sys.argv[0]) sambaopts = options.SambaOptions(parser) @@ -71,7 +72,7 @@ opts, args = parser.parse_args() lp = sambaopts.get_loadparm() -print "%s" % lp.get("server string") +print("%s" % lp.get("server string")) messaging_path = (opts.messaging_path or os.path.join(lp.get("private dir"), "smbd.tmp", "messaging")) @@ -85,7 +86,7 @@ else: conn = open_connection("smb_server") except RuntimeError, (num, msg): if msg == 'NT_STATUS_OBJECT_NAME_NOT_FOUND': - print "No active connections" + print("No active connections") else: show_sessions(conn) show_tcons(conn) diff --git a/source4/scripting/devel/addlotscontacts b/source4/scripting/devel/addlotscontacts index e8b2c1af1aa..73e2043509a 100644 --- a/source4/scripting/devel/addlotscontacts +++ b/source4/scripting/devel/addlotscontacts @@ -15,7 +15,7 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . - +from __future__ import print_function __docformat__ = "restructuredText" @@ -88,7 +88,7 @@ if __name__ == '__main__': "objectClass") if count !=0 and (count % increment) == 0: - print "Added contacts: %d" % count + print("Added contacts: %d" % count) ldbs.sam.add(msg) count += 1 diff --git a/source4/scripting/devel/crackname b/source4/scripting/devel/crackname index 0ae177c133f..d19d4968900 100755 --- a/source4/scripting/devel/crackname +++ b/source4/scripting/devel/crackname @@ -3,7 +3,7 @@ # Copyright Matthieu Patou 2011 # script to call a DRSUAPI crackname # this is useful for plugfest testing and replication debug - +from __future__ import print_function import sys from optparse import OptionParser @@ -71,8 +71,8 @@ if __name__ == "__main__": req.names = [names] (result, ctr) = drs.DsCrackNames(drs_handle, 1, req) - print "# of result = %d" %ctr.count + print("# of result = %d" %ctr.count) if ctr.count: - print "status = %d" % ctr.array[0].status - print "result name = %s" % ctr.array[0].result_name - print "domain = %s" % ctr.array[0].dns_domain_name + print("status = %d" % ctr.array[0].status) + print("result name = %s" % ctr.array[0].result_name) + print("domain = %s" % ctr.array[0].dns_domain_name) diff --git a/source4/scripting/devel/getncchanges b/source4/scripting/devel/getncchanges index 9c25e39f756..69d39bd5dd5 100755 --- a/source4/scripting/devel/getncchanges +++ b/source4/scripting/devel/getncchanges @@ -2,7 +2,7 @@ # script to call a DRS GetNCChanges from the command line # this is useful for plugfest testing - +from __future__ import print_function import sys from optparse import OptionParser @@ -98,17 +98,17 @@ if __name__ == "__main__": dest_dsa = opts.dest_dsa if not dest_dsa: - print "no dest_dsa specified trying to figure out from ldap" + print("no dest_dsa specified trying to figure out from ldap") msgs = samdb.search(controls=["search_options:1:2"], expression='(objectclass=ntdsdsa)') if len(msgs) == 1: dest_dsa = str(ndr_unpack(misc.GUID, msgs[0]["invocationId"][0])) - print "Found this dsa: %s" % dest_dsa + print("Found this dsa: %s" % dest_dsa) else: # TODO fixme pass if not dest_dsa: - print "Unable to find the dest_dsa automatically please specify it" + print("Unable to find the dest_dsa automatically please specify it") import sys sys.exit(1) -- 2.17.1 From 21299e21cdc64773460184faabe354c5eda718ef Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 20 May 2019 16:29:10 +1200 Subject: [PATCH 3/7] sambaundoguididx: Add flags=ldb.FLG_DONT_CREATE_DB and port to Python3 In py3 we need to add an extra str() around the returned ldb value to enable .split() to be used. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13978 Signed-off-by: Andrew Bartlett Reviewed By: Noel Power Autobuild-User(master): Noel Power Autobuild-Date(master): Thu May 23 14:25:52 UTC 2019 on sn-devel-184 (cherry picked from commit 1a9da378a1505daff498be6d6355debd73526a1a) --- source4/scripting/bin/sambaundoguididx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/source4/scripting/bin/sambaundoguididx b/source4/scripting/bin/sambaundoguididx index adff232e022..9a38851b421 100755 --- a/source4/scripting/bin/sambaundoguididx +++ b/source4/scripting/bin/sambaundoguididx @@ -34,7 +34,9 @@ if opts.H is None: else: url = opts.H -samdb = ldb.Ldb(url=url, options=["modules:"]) +samdb = ldb.Ldb(url=url, + flags=ldb.FLG_DONT_CREATE_DB, + options=["modules:"]) partitions = samdb.search(base="@PARTITION", scope=ldb.SCOPE_BASE, @@ -58,10 +60,11 @@ privatedir = os.path.dirname(url) dbs = [] for part in partitions[0]['partition']: - tdbname = part.split(":")[1] - tdbpath = os.path.join(privatedir, tdbname) - - db = ldb.Ldb(url=tdbpath, options=["modules:"]) + dbname = str(part).split(":")[1] + dbpath = os.path.join(privatedir, dbname) + db = ldb.Ldb(url="ldb://" + dbpath, + options=["modules:"], + flags=ldb.FLG_DONT_CREATE_DB) db.transaction_start() db.modify(modmsg) dbs.append(db) @@ -73,7 +76,8 @@ samdb.transaction_commit() print("Re-opening with the full DB stack") samdb = SamDB(url=url, - lp=lp_ctx) + flags=ldb.FLG_DONT_CREATE_DB, + lp=lp_ctx) print("Re-triggering another re-index") chk = dbcheck(samdb) -- 2.17.1 From d40d3639c7063bffabc8c2306320e0849ef1cffd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 20 May 2019 16:29:10 +1200 Subject: [PATCH 4/7] sambaundoguididx: fix for -s Quick fix running this script with -s instead of -H. samdb_url() returns a url with a protocol prefix, which causes issues further down in the script. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13978 Signed-off-by: Andrew Bartlett Reviewed-by: Garming Sam (cherry picked from commit 40ca8ed5a152ae7c5ec039649c09a037a20a4143) --- source4/scripting/bin/sambaundoguididx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source4/scripting/bin/sambaundoguididx b/source4/scripting/bin/sambaundoguididx index 9a38851b421..92405eab24d 100755 --- a/source4/scripting/bin/sambaundoguididx +++ b/source4/scripting/bin/sambaundoguididx @@ -30,7 +30,7 @@ lp_ctx = sambaopts.get_loadparm() lp_ctx.set("dsdb:guid index", "false") if opts.H is None: - url = lp_ctx.samdb_url() + url = lp_ctx.private_path("sam.ldb") else: url = opts.H @@ -62,7 +62,9 @@ dbs = [] for part in partitions[0]['partition']: dbname = str(part).split(":")[1] dbpath = os.path.join(privatedir, dbname) - db = ldb.Ldb(url="ldb://" + dbpath, + if os.path.isfile(dbpath): + dbpath = "ldb://" + dbpath + db = ldb.Ldb(url=dbpath, options=["modules:"], flags=ldb.FLG_DONT_CREATE_DB) db.transaction_start() -- 2.17.1 From 0d3601deb7f36557256aa9221e51f74a6c7b08f1 Mon Sep 17 00:00:00 2001 From: Aaron Haslett Date: Fri, 24 May 2019 14:37:50 +1200 Subject: [PATCH 5/7] sambaundoguididx: renamed to downgradedatabase In forthcoming commits we're going to repurpose this script to do an entire downgrade of a database, disabling all new database features. downgradedatabase is a more appropriate name. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13978 Signed-off-by: Aaron Haslett Reviewed-by: Andrew Bartlett Reviewed-by: Garming Sam (cherry picked from commit c0b679f6a3f21e262d03bf38ea63900d30c29bb5) --- .../scripting/bin/{sambaundoguididx => sambadowngradedatabase} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename source4/scripting/bin/{sambaundoguididx => sambadowngradedatabase} (100%) diff --git a/source4/scripting/bin/sambaundoguididx b/source4/scripting/bin/sambadowngradedatabase similarity index 100% rename from source4/scripting/bin/sambaundoguididx rename to source4/scripting/bin/sambadowngradedatabase -- 2.17.1 From c9ded795471c2e2396a52427971884a21cca8042 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 29 May 2019 16:36:00 +1200 Subject: [PATCH 6/7] sambadowngradedatabase: Add "or later" to warning about using tools from Samba 4.8 BUG: https://bugzilla.samba.org/show_bug.cgi?id=13978 Signed-off-by: Andrew Bartlett Reviewed-by: Garming Sam (cherry picked from commit 09f2a187b3d8c161e2c11588499b3256a9dbcc95) --- source4/scripting/bin/sambadowngradedatabase | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/scripting/bin/sambadowngradedatabase b/source4/scripting/bin/sambadowngradedatabase index 92405eab24d..89af12c52f5 100755 --- a/source4/scripting/bin/sambadowngradedatabase +++ b/source4/scripting/bin/sambadowngradedatabase @@ -87,5 +87,5 @@ chk.reindex_database() print("Your database has been downgraded to DN-based index values.") -print("NOTE: Any use of a Samba 4.8 tool including ldbsearch will " +print("NOTE: Any use of a Samba 4.8 or later tool including ldbsearch will " "auto-upgrade back to GUID index mode") -- 2.17.1 From 582765d8e89ba354a53d67aa92a20438cbbf6650 Mon Sep 17 00:00:00 2001 From: Aaron Haslett Date: Thu, 23 May 2019 13:21:19 +1200 Subject: [PATCH 7/7] downgradedatabase: blackbox test This test confirms that running downgradedatabase causes all GUID keys to be replaced with DN keys at the KV level BUG: https://bugzilla.samba.org/show_bug.cgi?id=13978 Signed-off-by: Aaron Haslett Reviewed-by: Andrew Bartlett Reviewed-by: Garming Sam (backported from commits 74d15c9bf76f0a2fb5fa7b7b1d80971d10c4fe45, ab376a97c972d2d5ebfb912ed90664c787860dc8 and 56400153c8c7052fe319f273c30c6d59556102dc to avoid changes to TestCaseInTempDir). ab376a97c972d2d5ebfb912ed90664c787860dc8 was: Signed-off-by: Andrew Bartlett Reviewed-by: Douglas Bagnall 56400153c8c7052fe319f273c30c6d59556102dc was: Signed-off-by: Andrew Bartlett Reviewed-by: Douglas Bagnall --- .../samba/tests/blackbox/downgradedatabase.py | 108 ++++++++++++++++++ source4/selftest/tests.py | 4 + 2 files changed, 112 insertions(+) create mode 100644 python/samba/tests/blackbox/downgradedatabase.py diff --git a/python/samba/tests/blackbox/downgradedatabase.py b/python/samba/tests/blackbox/downgradedatabase.py new file mode 100644 index 00000000000..7b0e3e06910 --- /dev/null +++ b/python/samba/tests/blackbox/downgradedatabase.py @@ -0,0 +1,108 @@ +# Blackbox tests for sambadowngradedatabase +# +# Copyright (C) Catalyst IT Ltd. 2019 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +from __future__ import print_function +from samba.tests import BlackboxTestCase +import os +import ldb +import shutil +from subprocess import check_output +from samba.samdb import SamDB + +COMMAND = os.path.join(os.path.dirname(__file__), + "../../../../../source4/scripting/bin/sambadowngradedatabase") + + +class DowngradeTest(BlackboxTestCase): + """Test that sambadowngradedatabase downgrades the samba database""" + backend = 'tdb' + + def setUp(self): + super(DowngradeTest, self).setUp() + + prov_cmd = "samba-tool domain provision " +\ + "--domain FOO --realm foo.example.com " +\ + "--targetdir {self.tempdir} " +\ + "--backend-store {self.backend} " +\ + "--host-name downgradetest " +\ + "--option=\"vfs objects=fake_acls xattr_tdb\"" + prov_cmd = prov_cmd.format(self=self) + self.check_run(prov_cmd, "Provisioning for downgrade") + + private_dir = os.path.join(self.tempdir, "private") + self.sam_path = os.path.join(private_dir, "sam.ldb") + self.ldb = ldb.Ldb(self.sam_path, options=["modules:"]) + + partitions = self.ldb.search(base="@PARTITION", + scope=ldb.SCOPE_BASE, + attrs=["partition"]) + partitions = partitions[0]['partition'] + partitions = [str(p).split(":")[1] for p in partitions] + self.dbs = [os.path.join(private_dir, p) + for p in partitions] + self.dbs.append(self.sam_path) + + def tearDown(self): + shutil.rmtree(os.path.join(self.tempdir, "private")) + shutil.rmtree(os.path.join(self.tempdir, "etc")) + shutil.rmtree(os.path.join(self.tempdir, "state")) + shutil.rmtree(os.path.join(self.tempdir, "bind-dns")) + shutil.rmtree(os.path.join(self.tempdir, "msg.lock")) + shutil.rmtree(os.path.join(self.tempdir, "cache")) + os.unlink(os.path.join(self.tempdir, "names.tdb")) + os.unlink(os.path.join(self.tempdir, "gencache_notrans.tdb")) + super(DowngradeTest, self).tearDown() + + # Parse out the comments above each record that ldbdump produces + # containing pack format version and KV level key for each record. + # Return all GUID keys and DN keys (without @attrs) + def ldbdump_keys_pack_formats(self): + # Get all comments from all partition dbs + comments = [] + for db in self.dbs: + dump = check_output(["bin/ldbdump", "-i", db]) + dump = dump.decode("utf-8") + dump = dump.split("\n") + comments += [s for s in dump if s.startswith("#")] + + guid_key_tag = "# key: GUID=" + guid_keys = {c[len(guid_key_tag):] for c in comments + if c.startswith(guid_key_tag)} + + dn_key_tag = "# key: DN=" + dn_keys = {c[len(dn_key_tag):] for c in comments + if c.startswith(dn_key_tag)} + + # Ignore @ attributes, they are always DN keyed + dn_keys_no_at_attrs = {d for d in dn_keys if not d.startswith("@")} + + return dn_keys_no_at_attrs, guid_keys + + # Check that sambadowngradedatabase replaces all GUID keys with DN keys + def test_downgrade_database(self): + dn_keys, guid_keys = self.ldbdump_keys_pack_formats() + self.assertGreater(len(guid_keys), 20) + self.assertEqual(len(dn_keys), 0) + + num_guid_keys_before_downgrade = len(guid_keys) + + self.check_run("%s -H %s" % (COMMAND, self.sam_path), + msg="Running sambadowngradedatabase") + + dn_keys, guid_keys = self.ldbdump_keys_pack_formats() + self.assertEqual(len(guid_keys), 0) + self.assertEqual(len(dn_keys), num_guid_keys_before_downgrade) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index d6fb388dc33..3f44c37a84f 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -806,6 +806,10 @@ for env in ["ad_dc_ntvfs:local", "ad_dc:local", "promoted_dc:local"]: planoldpythontestsuite(env, "samba.tests.blackbox.smbcontrol") +planoldpythontestsuite("none", "samba.tests.blackbox.downgradedatabase") + +planoldpythontestsuite("none", "samba.tests.blackbox.downgradedatabase") + 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']) plantestsuite_loadlist("samba4.tokengroups.ntlm.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', 'no', '$LOADLIST', '$LISTOPT']) -- 2.17.1