The branch, master has been updated via 761ce8cfe41 s4:kdc: Set kerberos debug class for kdc service via a88bb04ca23 selftest: Add Address Sanitizer suppressions via 7800097af4e selftest: Create asan_options variable via 1591d7bdbf0 selftest: Fix address sanitizer with python3 via 08dda9cefdd selftest: Remove tailing whitspaces in selftest.pl via 6b9018d3c98 waf: Do not use as-needed if we build with Address Sanitizer via b475e020664 s4:gensec: Do not link subsystems against dlopen() modules! via b5013634175 pytest samba-tool forest: use runcmd via 098886946fa make runcmd, runsubcmd, exact aliases via 273797d8cf9 pytest: samba-tool: coalesce run*cmd functions via 4bfcd16a3c6 samba-tool: binary uses samba_tool function via a1c615f87de pytest/samba-tool: entry function follows too logic via 8b23ef30032 pytest/password-lockout: fix using samba_tool function via 202182e0fdc pytest/samba_dnsupdate: fix using samba-tool function via c41887d903f pytest/netcmd: fix for new samba-tool api via 5247c87cc2c samba-tool: add a convenience function that does it all via 153ad8fc3a9 samba-tool: command that has exception, shows exception via 304ac5bb777 samba-tool: _resolve() can set outf, errf via ed787869897 samba-tool: more conventional usage of parser.parse_args via 9ec0863ff24 samba-tool: separate ._run() from command resolution via 8b403ab7c55 samba-tool: do not crash on unimplemented .run() from 8132edf1197 s3:libads: let cldap_ping_list() use cldap_multi_netlogon()
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 761ce8cfe41139ab5656dec5cc05f2f576095216 Author: Andreas Schneider <a...@samba.org> Date: Tue Sep 6 10:19:54 2022 +0200 s4:kdc: Set kerberos debug class for kdc service Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> Autobuild-User(master): Andrew Bartlett <abart...@samba.org> Autobuild-Date(master): Thu Sep 8 23:34:15 UTC 2022 on sn-devel-184 commit a88bb04ca233cbe19aa9bae1cc5078274785cb4d Author: Andreas Schneider <a...@samba.org> Date: Tue Sep 6 10:06:37 2022 +0200 selftest: Add Address Sanitizer suppressions Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 7800097af4e8ba071b31cecaf19a76b0e4b8a053 Author: Andreas Schneider <a...@samba.org> Date: Tue Sep 6 10:06:05 2022 +0200 selftest: Create asan_options variable Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 1591d7bdbf045bee45e7e2775a7be464fe236d1c Author: Andreas Schneider <a...@samba.org> Date: Tue Sep 6 08:59:56 2022 +0200 selftest: Fix address sanitizer with python3 ==9542==AddressSanitizer: failed to intercept 'crypt' ==9542==AddressSanitizer: failed to intercept 'crypt_r' [..] AddressSanitizer:DEADLYSIGNAL ================================================================= ==29768==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000000000 bp 0x7ffcec4bf3c0 sp 0x7ffcec4beb58 T0) ==29768==Hint: pc points to the zero page. ==29768==The signal is caused by a READ memory access. ==29768==Hint: address points to the zero page. #0 0x0 (<unknown module>) #1 0x7f052cca4129 in crypt_crypt_impl /usr/src/debug/python310-core-3.10.6-3.1.x86_64/Modules/_cryptmodule.c:44 We would need to build python without --as-needed as we can't so that we need to preload the library to avoid a segfault. See also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98669 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 08dda9cefdddf6953ac54b282e8b0e434426d1d6 Author: Andreas Schneider <a...@samba.org> Date: Tue Sep 6 08:48:49 2022 +0200 selftest: Remove tailing whitspaces in selftest.pl Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 6b9018d3c98113c6984a1fe65cce42771ccb4600 Author: Andreas Schneider <a...@samba.org> Date: Tue Sep 6 08:47:47 2022 +0200 waf: Do not use as-needed if we build with Address Sanitizer https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98669 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit b475e02066437920b671bdd0f91602f4f5b7c5f0 Author: Andreas Schneider <a...@samba.org> Date: Thu Sep 8 10:32:38 2022 +0200 s4:gensec: Do not link subsystems against dlopen() modules! This is not a shared library. This only worked because we use '--as-needed' as linker option. Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit b5013634175ef4b0a32e120e8b5806ad7283623b Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Wed Sep 7 22:17:41 2022 +1200 pytest samba-tool forest: use runcmd This is an example/test to show how runsublevelcmd() converts into runcmd() whilst ensuring it works. Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 098886946fae21e67574cf931047bdae233cbbf0 Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Wed Sep 7 22:17:05 2022 +1200 make runcmd, runsubcmd, exact aliases Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 273797d8cf937eaa9262ad5b9f860d3f9a0fb0c4 Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Wed Sep 7 16:57:46 2022 +1200 pytest: samba-tool: coalesce run*cmd functions We have had three different functions for resolving samba-tool commands, depending on whether they are nested 1, 2, or n deep (where n could also be 1 or 2). This API evolved around a separation of sub-command names and options, so that the Command that was eventually found could be given the right outf and errf. Now we can just use the same outf and errf for all levels, and we can not care about this distinction. All these functions are now synonyms, and we keep them all for now for backward-compatibility. Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 4bfcd16a3c6af3fc21d9c57f8fbdb2ea5fd15f25 Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Thu Sep 8 10:17:54 2022 +1200 samba-tool: binary uses samba_tool function Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit a1c615f87de8184eeb7ba7fb5f959a0b6a5ccac3 Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Thu Sep 8 20:27:33 2022 +1200 pytest/samba-tool: entry function follows too logic To further align the logic of the tool and the tests, we use the same logic in the test function as in samba-tool. In effect, this means the function is even less likely to raise an exception, rahter printing it out and returning an error code. Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 8b23ef30032416e074efbe6db991dfb0744eb54d Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Wed Sep 7 22:04:08 2022 +1200 pytest/password-lockout: fix using samba_tool function Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 202182e0fdc58388a5c4b0de0b94aa5431c01018 Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Wed Sep 7 22:03:16 2022 +1200 pytest/samba_dnsupdate: fix using samba-tool function Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit c41887d903fc5a4f384dd6ef2166fd6288406e11 Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Wed Sep 7 22:03:47 2022 +1200 pytest/netcmd: fix for new samba-tool api In this case we are skipping _resolve(). Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 5247c87cc2ce756196a1d0354d20327870cb36a4 Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Thu Sep 8 10:00:36 2022 +1200 samba-tool: add a convenience function that does it all Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 153ad8fc3a90446fe25108a8ba4f41812e9b2462 Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Thu Sep 8 08:56:45 2022 +1200 samba-tool: command that has exception, shows exception This will make a difference to the string printed in the cases that call self.usage(), resulting in more specified usage for the sub-command. It would also matter if the samba-tool sub-command had a different .show_command_error() or .errf, but I don't think that happens. Note: usually command._run() will have caught and shown the exception, returning -1. We also rename away 'cmd' so we don't again imagine it is the command we are running. Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 304ac5bb777029701b79b4f64370643865d3ee4f Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Wed Sep 7 16:33:33 2022 +1200 samba-tool: _resolve() can set outf, errf We catch output in outf and errf for testing, which we currently do with cmd.outf = self.stringIO() cmd.errf = self.stringIO() on the final resolved commands. But this does not catch the output of the super-commands, of which we normally expect none. Using supercmd._resolve(*args, outf=self.stringIO(), errf=self.stringIO()) will redirect output all the way up the chain. Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit ed78786989779f31d97de2aa81b06ef0c0ad7f39 Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Wed Sep 7 15:07:43 2022 +1200 samba-tool: more conventional usage of parser.parse_args By default parse_args will use sys.argv[1:], which is to say the command-line without the command name. We have always fed it the equivalent of sys.argv, then trimmed the command off the result. That was a bit silly. Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 9ec0863ff244494ba1b3fdc1b2d3be38e195e146 Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Wed Sep 7 15:34:23 2022 +1200 samba-tool: separate ._run() from command resolution Prior to this commit, in super-commands, the first half of the _run() is resolving what sub-command to run, and the second half is working out what to print if that failed. Some issues with that are: * it looks a little bit complicated. * the tests can't use the tool's resolution code, because it runs immediately, while the tests first want to fiddle with self.outf and so on. * it makes it harder to subclass and override the resolution code, so instead we do strange things like where we subclass dict as in main.py. So we split it into ._resolve() and ._run(). There are a few tests that break. We mark these as flapping, rather than knownfail, so as to avoid going into extremely fine-grain filters for tests that will be fixed within a few commits. Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 8b403ab7c55aa3f269b38b19553f50303012025c Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Tue Aug 16 13:43:54 2022 +1200 samba-tool: do not crash on unimplemented .run() The run() method is always called with arguments, so it crashes before the NotImplementedError() is ever reached. That's OK, but this is better. Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> ----------------------------------------------------------------------- Summary of changes: python/samba/netcmd/__init__.py | 100 ++++++++++++++++--------- python/samba/netcmd/main.py | 14 ++++ python/samba/tests/blackbox/samba_dnsupdate.py | 20 ++--- python/samba/tests/netcmd.py | 3 +- python/samba/tests/samba_tool/base.py | 41 +++------- python/samba/tests/samba_tool/forest.py | 23 +++--- selftest/sanitizer/asan.supp | 2 + selftest/selftest.pl | 24 ++++-- selftest/wscript | 27 +++++-- source4/auth/gensec/wscript_build | 2 +- source4/dsdb/tests/python/password_lockout.py | 12 ++- source4/kdc/kdc-service-mit.c | 3 + source4/scripting/bin/samba-tool | 18 +---- source4/scripting/bin/samba_dnsupdate | 3 +- wscript | 3 +- 15 files changed, 171 insertions(+), 124 deletions(-) create mode 100644 selftest/sanitizer/asan.supp Changeset truncated at 500 lines: diff --git a/python/samba/netcmd/__init__.py b/python/samba/netcmd/__init__.py index 73292489268..874f553e910 100644 --- a/python/samba/netcmd/__init__.py +++ b/python/samba/netcmd/__init__.py @@ -89,9 +89,14 @@ class Command(object): raw_args = None raw_kwargs = None + def _set_files(self, outf=None, errf=None): + if outf is not None: + self.outf = outf + if errf is not None: + self.errf = errf + def __init__(self, outf=sys.stdout, errf=sys.stderr): - self.outf = outf - self.errf = errf + self._set_files(outf, errf) def usage(self, prog=None): parser, _ = self._create_parser(prog) @@ -158,11 +163,16 @@ class Command(object): def message(self, text): self.outf.write(text + "\n") + def _resolve(self, path, *argv, outf=None, errf=None): + """This is a leaf node, the command that will actually run.""" + self._set_files(outf, errf) + self.command_name = path + return (self, argv) + def _run(self, *argv): - parser, optiongroups = self._create_parser(argv[0]) + parser, optiongroups = self._create_parser(self.command_name) opts, args = parser.parse_args(list(argv)) # Filter out options from option groups - args = args[1:] kwargs = dict(opts.__dict__) for option_group in parser.option_groups: for option in option_group.option_list: @@ -198,9 +208,9 @@ class Command(object): self.show_command_error(e) return -1 - def run(self): + def run(self, *args, **kwargs): """Run the command. This should be overridden by all subclasses.""" - raise NotImplementedError(self.run) + raise NotImplementedError(f"'{self.command_name}' run method not implemented") def get_logger(self, name="", verbose=False, quiet=False, **kwargs): """Get a logger object.""" @@ -229,43 +239,61 @@ class SuperCommand(Command): subcommands = {} - def _run(self, myname, subcommand=None, *args): - if subcommand in self.subcommands: - return self.subcommands[subcommand]._run( - "%s %s" % (myname, subcommand), *args) - elif subcommand not in [ '--help', 'help', None, '-h', '-V', '--version' ]: - print("%s: no such subcommand: %s\n" % (myname, subcommand)) - args = [] - - if subcommand == 'help': - # pass the request down - if len(args) > 0: - sub = self.subcommands.get(args[0]) - if isinstance(sub, SuperCommand): - return sub._run("%s %s" % (myname, args[0]), 'help', - *args[1:]) - elif sub is not None: - return sub._run("%s %s" % (myname, args[0]), '--help', - *args[1:]) - - subcommand = '--help' + def _resolve(self, path, *args, outf=None, errf=None): + """This is an internal node. We need to consume one of the args and + find the relevant child, returning an instance of that Command. + + If there are no children, this SuperCommand will be returned + and its _run() will do a --help like thing. + """ + self.command_name = path + self._set_files(outf, errf) + + # We collect up certain option arguments and pass them to the + # leaf, which is why we iterate over args, though we really + # expect to return in the first iteration. + deferred_args = [] + + for i, a in enumerate(args): + if a in self.subcommands: + sub_args = args[i + 1:] + tuple(deferred_args) + sub_path = f'{path} {a}' + + sub = self.subcommands[a] + return sub._resolve(sub_path, *sub_args, outf=outf, errf=errf) + elif a in [ '--help', 'help', None, '-h', '-V', '--version' ]: + # we pass these to the leaf node. + if a == 'help': + a = '--help' + deferred_args.append(a) + continue + + # they are talking nonsense + print("%s: no such subcommand: %s\n" % (path, a), file=self.outf) + return (self, []) + + # We didn't find a subcommand, but maybe we found e.g. --version + print("%s: missing subcommand\n" % (path), file=self.outf) + return (self, deferred_args) + + def _run(self, *argv): epilog = "\nAvailable subcommands:\n" subcmds = list(self.subcommands.keys()) subcmds.sort() max_length = max([len(c) for c in subcmds]) for cmd_name in subcmds: cmd = self.subcommands[cmd_name] - if not cmd.hidden: - epilog += " %*s - %s\n" % ( - -max_length, cmd_name, cmd.short_description) - epilog += "For more help on a specific subcommand, please type: %s <subcommand> (-h|--help)\n" % myname - - parser, optiongroups = self._create_parser(myname, epilog=epilog) - args_list = list(args) - if subcommand: - args_list.insert(0, subcommand) - opts, args = parser.parse_args(args_list) + if cmd.hidden: + continue + epilog += " %*s - %s\n" % ( + -max_length, cmd_name, cmd.short_description) + + epilog += ("For more help on a specific subcommand, please type: " + f"{self.command_name} <subcommand> (-h|--help)\n") + + parser, optiongroups = self._create_parser(self.command_name, epilog=epilog) + opts, args = parser.parse_args(list(argv)) parser.print_help() return -1 diff --git a/python/samba/netcmd/main.py b/python/samba/netcmd/main.py index 88c33c5aa1a..0fd4f20d941 100644 --- a/python/samba/netcmd/main.py +++ b/python/samba/netcmd/main.py @@ -81,3 +81,17 @@ class cmd_sambatool(SuperCommand): subcommands["ou"] = None subcommands["processes"] = None subcommands["visualize"] = None + + +def samba_tool(*args, **kwargs): + """A single function that runs samba-tool, returning an error code on + error, and None on success.""" + try: + cmd, argv = cmd_sambatool()._resolve("samba-tool", *args, **kwargs) + ret = cmd._run(*argv) + except SystemExit as e: + ret = e.code + except Exception as e: + cmd.show_command_error(e) + ret = 1 + return ret diff --git a/python/samba/tests/blackbox/samba_dnsupdate.py b/python/samba/tests/blackbox/samba_dnsupdate.py index f51ee4dff27..8fcdd207f73 100644 --- a/python/samba/tests/blackbox/samba_dnsupdate.py +++ b/python/samba/tests/blackbox/samba_dnsupdate.py @@ -19,7 +19,7 @@ import samba.tests from io import StringIO from samba.common import get_string -from samba.netcmd.main import cmd_sambatool +from samba.netcmd.main import samba_tool from samba.credentials import Credentials from samba.auth import system_session from samba.samdb import SamDB @@ -71,17 +71,17 @@ class SambaDnsUpdateTests(samba.tests.BlackboxTestCase): self.assertTrue(b"No DNS updates needed" in out, out + rpc_out) def test_add_new_uncovered_site(self): - name = 'sites' - cmd = cmd_sambatool.subcommands[name] - cmd.outf = StringIO() - cmd.errf = StringIO() - site_name = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' # Clear out any existing site - cmd._run("samba-tool %s" % name, 'remove', site_name) + result = samba_tool('sites', 'remove', site_name, + outf=StringIO(), + errf=StringIO()) + + result = samba_tool('sites', 'create', site_name, + outf=StringIO(), + errf=StringIO()) - result = cmd._run("samba-tool %s" % name, 'create', site_name) if result is not None: self.fail("Error creating new site") @@ -118,6 +118,8 @@ class SambaDnsUpdateTests(samba.tests.BlackboxTestCase): self.assertNotIn("No DNS updates needed", out) self.assertIn(site_name.lower(), out) - result = cmd._run("samba-tool %s" % name, 'remove', site_name) + result = samba_tool('sites', 'remove', site_name, + outf=StringIO(), + errf=StringIO()) if result is not None: self.fail("Error deleting site") diff --git a/python/samba/tests/netcmd.py b/python/samba/tests/netcmd.py index 833ad418923..63f204a2c23 100644 --- a/python/samba/tests/netcmd.py +++ b/python/samba/tests/netcmd.py @@ -31,8 +31,9 @@ class NetCmdTestCase(samba.tests.TestCaseInTempDir): def run_netcmd(self, cmd_klass, args, retcode=0): cmd = cmd_klass(outf=StringIO(), errf=StringIO()) + cmd.command_name = "apricots" try: - retval = cmd._run(cmd_klass.__name__, *args) + retval = cmd._run(*args) except Exception as e: cmd.show_command_error(e) retval = 1 diff --git a/python/samba/tests/samba_tool/base.py b/python/samba/tests/samba_tool/base.py index 728ed1139d0..76299f8023d 100644 --- a/python/samba/tests/samba_tool/base.py +++ b/python/samba/tests/samba_tool/base.py @@ -72,41 +72,22 @@ class SambaToolCmdTest(samba.tests.BlackboxTestCase): credentials=creds, lp=lp) return samdb - def runcmd(self, name, *args): - """run a single level command""" - cmd = cmd_sambatool.subcommands[name] - cmd.outf = self.stringIO() - cmd.errf = self.stringIO() - result = cmd._run("samba-tool %s" % name, *args) + def _run(self, *argv): + """run a samba-tool command""" + cmd, args = cmd_sambatool()._resolve('samba-tool', *argv, + outf=self.stringIO(), + errf=self.stringIO()) + result = cmd._run(*args) return (result, cmd.outf.getvalue(), cmd.errf.getvalue()) - def runsubcmd(self, name, sub, *args): - """run a command with sub commands""" - # The reason we need this function separate from runcmd is - # that the .outf StringIO assignment is overridden if we use - # runcmd, so we can't capture stdout and stderr - cmd = cmd_sambatool.subcommands[name].subcommands[sub] - cmd.outf = self.stringIO() - cmd.errf = self.stringIO() - result = cmd._run("samba-tool %s %s" % (name, sub), *args) - return (result, cmd.outf.getvalue(), cmd.errf.getvalue()) + runcmd = _run + runsubcmd = _run def runsublevelcmd(self, name, sublevels, *args): """run a command with any number of sub command levels""" - # Same as runsubcmd, except this handles a varying number of sub-command - # levels, e.g. 'samba-tool domain passwordsettings pso set', whereas - # runsubcmd() only handles exactly one level of sub-commands. - # First, traverse the levels of sub-commands to get the actual cmd - # object we'll run, and construct the cmd string along the way - cmd = cmd_sambatool.subcommands[name] - cmd_str = "samba-tool %s" % name - for sub in sublevels: - cmd = cmd.subcommands[sub] - cmd_str += " %s" % sub - cmd.outf = self.stringIO() - cmd.errf = self.stringIO() - result = cmd._run(cmd_str, *args) - return (result, cmd.outf.getvalue(), cmd.errf.getvalue()) + # This is a weird and clunky interface for running a + # subcommand. Use self.runcmd() instead. + return self._run(name, *sublevels, *args) def assertCmdSuccess(self, exit, out, err, msg=""): # Make sure we allow '\n]\n' in stdout and stderr diff --git a/python/samba/tests/samba_tool/forest.py b/python/samba/tests/samba_tool/forest.py index f5cb3c03126..25eeb4ccedb 100644 --- a/python/samba/tests/samba_tool/forest.py +++ b/python/samba/tests/samba_tool/forest.py @@ -43,11 +43,12 @@ class ForestCmdTestCase(SambaToolCmdTest): def test_display(self): """Tests that we can display forest settings""" - (result, out, err) = self.runsublevelcmd("forest", ("directory_service", - "show"), - "-H", "ldap://%s" % os.environ["DC_SERVER"], - "-U%s%%%s" % (os.environ["DC_USERNAME"], - os.environ["DC_PASSWORD"])) + (result, out, err) = self.runcmd("forest", + "directory_service", + "show", + "-H", "ldap://%s" % os.environ["DC_SERVER"], + "-U%s%%%s" % (os.environ["DC_USERNAME"], + os.environ["DC_PASSWORD"])) self.assertCmdSuccess(result, out, err) self.assertEqual(err, "", "Shouldn't be any error messages") @@ -56,11 +57,13 @@ class ForestCmdTestCase(SambaToolCmdTest): def test_modify_dsheuristics(self): """Test that we can modify the dsheuristics setting""" - (result, out, err) = self.runsublevelcmd("forest", ("directory_service", - "dsheuristics"), "0000002", - "-H", "ldap://%s" % os.environ["DC_SERVER"], - "-U%s%%%s" % (os.environ["DC_USERNAME"], - os.environ["DC_PASSWORD"])) + (result, out, err) = self.runcmd("forest", + "directory_service", + "dsheuristics", + "0000002", + "-H", "ldap://%s" % os.environ["DC_SERVER"], + "-U%s%%%s" % (os.environ["DC_USERNAME"], + os.environ["DC_PASSWORD"])) self.assertCmdSuccess(result, out, err) self.assertEqual(err, "", "Shouldn't be any error messages") diff --git a/selftest/sanitizer/asan.supp b/selftest/sanitizer/asan.supp new file mode 100644 index 00000000000..df548339ab6 --- /dev/null +++ b/selftest/sanitizer/asan.supp @@ -0,0 +1,2 @@ +interceptor_via_lib:libcrypto.so +interceptor_via_lib:libgnutls.so diff --git a/selftest/selftest.pl b/selftest/selftest.pl index 75763ef3838..11f8e92e84e 100755 --- a/selftest/selftest.pl +++ b/selftest/selftest.pl @@ -62,6 +62,7 @@ my $opt_libresolv_wrapper_so_path = ""; my $opt_libsocket_wrapper_so_path = ""; my $opt_libuid_wrapper_so_path = ""; my $opt_libasan_so_path = ""; +my $opt_libcrypt_so_path = ""; my $opt_use_dns_faking = 0; my @testlists = (); @@ -208,7 +209,7 @@ DNS: Target Specific: --socket-wrapper-pcap save traffic to pcap directories - --socket-wrapper-keep-pcap keep all pcap files, not just those for tests that + --socket-wrapper-keep-pcap keep all pcap files, not just those for tests that failed --socket-wrapper enable socket wrapper @@ -248,6 +249,7 @@ my $result = GetOptions ( 'socket_wrapper_so_path=s' => \$opt_libsocket_wrapper_so_path, 'uid_wrapper_so_path=s' => \$opt_libuid_wrapper_so_path, 'asan_so_path=s' => \$opt_libasan_so_path, + 'crypt_so_path=s' => \$opt_libcrypt_so_path, 'use-dns-faking' => \$opt_use_dns_faking ); @@ -346,9 +348,17 @@ my $ld_preload = $ENV{LD_PRELOAD}; if ($opt_libasan_so_path) { if ($ld_preload) { - $ld_preload = "$opt_libasan_so_path:$ld_preload"; + if ($opt_libcrypt_so_path) { + $ld_preload = "$opt_libasan_so_path:$opt_libcrypt_so_path:$ld_preload"; + } else { + $ld_preload = "$opt_libasan_so_path:$ld_preload"; + } } else { - $ld_preload = "$opt_libasan_so_path"; + if ($opt_libcrypt_so_path) { + $ld_preload = "$opt_libasan_so_path:$opt_libcrypt_so_path"; + } else { + $ld_preload = "$opt_libasan_so_path"; + } } } @@ -464,14 +474,14 @@ sub read_test_regexes($) my ($name) = @_; my @ret = (); open(LF, "<$name") or die("unable to read $name: $!"); - while (<LF>) { - chomp; + while (<LF>) { + chomp; next if (/^#/); if (/^(.*?)([ \t]+)\#([\t ]*)(.*?)$/) { push (@ret, [$1, $4]); } else { s/^(.*?)([ \t]+)\#([\t ]*)(.*?)$//; - push (@ret, [$_, undef]); + push (@ret, [$_, undef]); } } close(LF); @@ -981,7 +991,7 @@ $envvarstr next; } - # Generate a file with the individual tests to run, if the + # Generate a file with the individual tests to run, if the # test runner for this test suite supports it. if ($individual_tests and $individual_tests->{$name}) { if ($$_[3]) { diff --git a/selftest/wscript b/selftest/wscript index a8b6d45cd1d..dd25f595a1d 100644 --- a/selftest/wscript +++ b/selftest/wscript @@ -281,6 +281,7 @@ def cmd_testonly(opt): if os.environ.get('DISABLE_OPATH'): env.OPTIONS += " --exclude=${srcdir}/selftest/skip.opath-required" + libasan = None if env.ADDRESS_SANITIZER: # We try to find the correct libasan automatically libasan = Utils.cmd_output( @@ -291,6 +292,14 @@ def cmd_testonly(opt): # Have the selftest.pl LD_PRELOAD libasan in the right spot env.OPTIONS += " --asan_so_path=" + libasan + if CONFIG_SET(opt, 'HAVE_CRYPT_R'): + # We try to find the correct libcrypt automatically + libcrypt = Utils.cmd_output( + 'ldd bin/modules/ldb/password_hash.so | awk \'/libcrypt.so/ { print $3 }\'', + silent=True).strip() + libcrypt = libcrypt.decode('utf8') + env.OPTIONS += " --crypt_so_path=" + libcrypt + subunit_cache = None # We use the full path rather than relative path to avoid problems on some platforms (ie. solaris 8). env.CORE_COMMAND = '${PERL} ${srcdir}/selftest/selftest.pl --target=${SELFTEST_TARGET} --prefix=${SELFTEST_PREFIX} --srcdir=${srcdir} --exclude=${srcdir}/selftest/skip ${TESTLISTS} ${OPTIONS} ${TESTS}' @@ -302,20 +311,28 @@ def cmd_testonly(opt): if os.environ.get('USE_NAMESPACES') is not None: env.CORE_COMMAND = 'unshare --net --user --map-root-user ' + env.CORE_COMMAND - if env.ADDRESS_SANITIZER: + if env.ADDRESS_SANITIZER and libasan: # For now we cannot run with leak and odr detection - no_leak_check = "ASAN_OPTIONS=detect_leaks=0:detect_odr_violation=0 " + asan_options = "ASAN_OPTIONS=detect_leaks=0" + asan_options += ":detect_odr_violation=0" + # uncomment if you need asan logs + # asan_options += ":verbosity=111" + asan_options += ":suppressions=${srcdir}/selftest/sanitizer/asan.supp" + asan_options += " " + # And we need to disable RTLD_DEEPBIND in ldb and socket wrapper - no_leak_check += "LDB_MODULES_DISABLE_DEEPBIND=1 " + no_leak_check = "LDB_MODULES_DISABLE_DEEPBIND=1 " no_leak_check += "SOCKET_WRAPPER_DISABLE_DEEP_BIND=1" - env.CORE_COMMAND = no_leak_check + " " + env.CORE_COMMAND + no_leak_check += " " + env.CORE_COMMAND = asan_options + no_leak_check + env.CORE_COMMAND # We need to have the subunit filter and formatter preload # libasan otherwise the tests fail at startup. # # Also, we do not care about leaks in python - asan_envs = no_leak_check + " LD_PRELOAD=" + libasan + ' ' + asan_envs = (asan_options + no_leak_check + "LD_PRELOAD=" + libasan + + ' ') env.FILTER_OPTIONS = asan_envs + env.FILTER_OPTIONS env.SUBUNIT_FORMATTER = asan_envs + env.SUBUNIT_FORMATTER diff --git a/source4/auth/gensec/wscript_build b/source4/auth/gensec/wscript_build index 20271f1665b..2885eb0a948 100644 --- a/source4/auth/gensec/wscript_build +++ b/source4/auth/gensec/wscript_build @@ -20,7 +20,7 @@ bld.SAMBA_MODULE('gensec_krb5', bld.SAMBA_SUBSYSTEM('gensec_krb5_helpers', source='gensec_krb5_helpers.c', - deps='gensec_krb5', + deps='talloc authkrb5', enabled=bld.AD_DC_BUILD_IS_ENABLED()) bld.SAMBA_MODULE('gensec_gssapi', diff --git a/source4/dsdb/tests/python/password_lockout.py b/source4/dsdb/tests/python/password_lockout.py index ed0502967e3..325c0cfdd01 100755 --- a/source4/dsdb/tests/python/password_lockout.py +++ b/source4/dsdb/tests/python/password_lockout.py @@ -16,7 +16,7 @@ sys.path.insert(0, "bin/python") import samba from samba.tests.subunitrun import TestProgram, SubunitOptions -from samba.netcmd.main import cmd_sambatool +from samba.netcmd.main import samba_tool import samba.getopt as options @@ -143,12 +143,10 @@ lockoutTime: 0 def _reset_samba_tool(self, res): -- Samba Shared Repository