[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Thu Sep 8 23:35:01 UTC 2022


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 <asn at 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 <asn at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Thu Sep  8 23:34:15 UTC 2022 on sn-devel-184

commit a88bb04ca233cbe19aa9bae1cc5078274785cb4d
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Sep 6 10:06:37 2022 +0200

    selftest: Add Address Sanitizer suppressions
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 7800097af4e8ba071b31cecaf19a76b0e4b8a053
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Sep 6 10:06:05 2022 +0200

    selftest: Create asan_options variable
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 1591d7bdbf045bee45e7e2775a7be464fe236d1c
Author: Andreas Schneider <asn at 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 <asn at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 08dda9cefdddf6953ac54b282e8b0e434426d1d6
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Sep 6 08:48:49 2022 +0200

    selftest: Remove tailing whitspaces in selftest.pl
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 6b9018d3c98113c6984a1fe65cce42771ccb4600
Author: Andreas Schneider <asn at 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 <asn at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit b475e02066437920b671bdd0f91602f4f5b7c5f0
Author: Andreas Schneider <asn at 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 <asn at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit b5013634175ef4b0a32e120e8b5806ad7283623b
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 098886946fae21e67574cf931047bdae233cbbf0
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Sep 7 22:17:05 2022 +1200

    make runcmd, runsubcmd, exact aliases
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 273797d8cf937eaa9262ad5b9f860d3f9a0fb0c4
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 4bfcd16a3c6af3fc21d9c57f8fbdb2ea5fd15f25
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit a1c615f87de8184eeb7ba7fb5f959a0b6a5ccac3
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 8b23ef30032416e074efbe6db991dfb0744eb54d
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 202182e0fdc58388a5c4b0de0b94aa5431c01018
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit c41887d903fc5a4f384dd6ef2166fd6288406e11
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 5247c87cc2ce756196a1d0354d20327870cb36a4
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 153ad8fc3a90446fe25108a8ba4f41812e9b2462
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 304ac5bb777029701b79b4f64370643865d3ee4f
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit ed78786989779f31d97de2aa81b06ef0c0ad7f39
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 9ec0863ff244494ba1b3fdc1b2d3be38e195e146
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 8b403ab7c55aa3f269b38b19553f50303012025c
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at 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



More information about the samba-cvs mailing list